用Python实现(第三方登录)使用GitHub账号登录(OAuth Python请求示例)
本文学习自阮一峰的网络日志,经自己使用Python完成功能!
今天演示一个示例,如何通过OAuth
获取API
数据。
很多网站登录时,允许使用第三方网站的身份,这称为第三方登录。
下面就以 GitHub 为例,写一个最简单的应用,演示第三方登录。
一、第三方登录的原理
所谓第三方登录,实质就是 OAuth 授权。用户想要登录 A 网站,A 网站让用户提供第三方网站的数据,证明自己的身份。获取第三方网站的身份数据,就需要 OAuth 授权。
举例来说,A 网站允许 GitHub 登录,背后就是下面的流程:
- A 网站让用户跳转到 GitHub。
- GitHub 要求用户登录,然后询问 “A 网站要求获得 XX 权限,你是否同意?”
- 用户同意,GitHub 就会重定向回 A 网站,同时发回一个授权码。
- A 网站使用授权码,向 GitHub 请求令牌。
- GitHub 返回令牌。
- A 网站使用令牌,向 GitHub 请求用户数据。
下面就是这个流程的代码实现。
二、应用登记
一个应用要求 OAuth 授权,必须先到对方网站登记,让对方知道是谁在请求。
所以,你要先去 GitHub 登记一下。大家需要自己登记一下;这是免费的。
访问GitHub 注册 OAuth APP网址,填写登记表。
应用的名称随便填,主页 URL 填写 http://localhost:8000
,跳转网址填写 http://localhost:8000/customer/github/redirect
。
提交表单以后,GitHub 应该会返回客户端 ID(cliend ID) 和客户端密钥(client secret),这就是应用的身份识别码。
三、Python代码实现
示例的后端采用 Django
框架编写。
浏览器跳转 GitHub
<a href="https://github.com/login/oauth/authorize?client_id=f77203148c0188ac5ffb&redirect_uri=http://localhost:8000/customer/github/redirect">使用GitHub账号登录</a>
这是一个 a链接,用来跳转到GitHub登录认证页面。
注意:大家可以直接写一个html文件,将上面的 a链接 放进去即可
跳转的URL部分如下:
'https://github.com/login/oauth/authorize?client_id=f77203148c0188ac5ffb&redirect_uri=http://localhost:8000/customer/github/redirect'
这个 URL 指向 GitHub 的 OAuth 授权网址,带有两个参数:client_id 告诉GitHub谁在请求,redirect_uri 是稍后跳转回来的网址。
用户点击 a链接 跳转到GitHub,GitHub会要求用户登录,确保是本人在操作。
用户同意授权,GitHub就会跳转到redirect_uri
指定的跳转网址,并且带上授权码,跳转回来的URL
就是下面的样子。
http://localhost:8000/customer/github/redirect?code=8ed33f770dbe57a924c7
后端受到这个请求以后,就拿到了授权码(code
参数)。
这里的关键是针对 /customer/github/redirect
的请求,编写一个路由,完成 OAuth 认证。
URL配置
注意:这里的 用户登录的APP 是我之前已经写好的一个用户登录APP,大家可以直接写一个测试APP
在用户登录的APP/urls.py文件中添加:
from . import githubviews
urlpatterns = [
path('github/redirect', githubviews.github_redirect, name='github_redirect'),
]
当然,需要新创建一个专门用于处理使用 GitHub 登录的视图文件:githubviews.py;
并且,在其中创建一个新的视图函数:github_redirect;
github_redirect 函数就是路由的处理(视图)函数;下面你的代码都写在这个函数里面。
视图函数的第一件事,是从 URL 中取出授权码。
视图代码
def github_redirect(request):
req_info = request.GET # 获取请求信息
req_code = req_info.get('code', None) # 获取授权码
视图代码目前只是初步完成了获取code
参数,稍后会将继续完善。
令牌
后端使用这个授权码,向 GitHub 请求令牌。
这是我写的一个方法,用来请求 GitHub 以获取 access_token 值:
def github_token(code):
"""
通过传入的 code 参数,带上client_id、client_secret、和code请求GitHub,以获取access_token
:param code: 重定向获取到的code参数
:return: 成功返回acces_token;失败返回None;
"""
token_url = 'https://github.com/login/oauth/access_token?' \
'client_id={}&client_secret={}&code={}'
token_url = token_url.format(client_id, client_secret, code) # 这里的client_id、client_secret修改为自己的真实ID与Secret
header = {
'accept': 'application/json'
}
res = requests.post(token_url, headers = header)
if res.status_code == 200:
res_dict = res.json()
print(res_dict)
return res_dict['access_token']
return None
上面代码中,GitHub 的令牌接口 https://github.com/login/oauth/access_token
需要提供三个参数。
- client_id:客户端的 ID
- client_secret:客户端的密钥
- code:授权码
作为回应,GitHub 会返回一段 JSON
数据,里面包含了令牌access_token
。
API数据
有了令牌以后,就可以向 API 请求数据了。
这是我写的一个用于向GitHub用户API请求数据的方法:
def github_user(access_token):
"""
通过传入的access_token,带上access_token参数,向GitHub用户API发送请求以获取用户信息;
:param access_token: 用于访问API的token
:return: 成功返回用户信息,失败返回None
"""
user_url = 'https://api.github.com/user'
access_token = 'token {}'.format(access_token)
headers = {
'accept': 'application/json',
'Authorization': access_token
}
res = requests.get(user_url, headers=headers)
if res.status_code == 200:
user_info = res.json()
print(user_info)
user_name = user_info.get('name', None)
return user_info
return None
上面代码中,GitHub API 的地址是https://api.github.com/user
,请求的时候必须在 HTTP头信息 里面带上令牌 Authorization: token 121212aa
。
然后,就可以拿到用户数据,得到用户的身份。
最后,视图代码经过初步完善后:
def github_redirect(request):
req_info = request.GET # 获取请求信息
req_code = req_info.get('code', None) # 获取授权码
if req_code:
access_token = github_token(req_code) # 向GitHub发送请求以获取access_token
if access_token:
user_info = github_user(access_token) # 向GitHub用户API发送请求获取信息
if user_info:
user_name = user_info.get('name', None)
return HttpResponse(user_name)
return HttpResponse('获取token失败,请重试!')
return HttpResponse('获取code参数失败,请重试!')
大家可以根据自己的项目或APP来进行数据的处理与使用。
本文学习自阮一峰的网络日志,经自己使用Python完成功能!