您的位置:首页 > 编程语言 > Python开发

用Python实现(第三方登录)使用GitHub账号登录(OAuth Python请求示例)

2019-04-22 10:41 561 查看

用Python实现(第三方登录)使用GitHub账号登录(OAuth Python请求示例)

本文学习自阮一峰的网络日志,经自己使用Python完成功能!

今天演示一个示例,如何通过

OAuth
获取
API
数据。

很多网站登录时,允许使用第三方网站的身份,这称为第三方登录

下面就以 GitHub 为例,写一个最简单的应用,演示第三方登录。

一、第三方登录的原理

所谓第三方登录,实质就是 OAuth 授权。用户想要登录 A 网站,A 网站让用户提供第三方网站的数据,证明自己的身份。获取第三方网站的身份数据,就需要 OAuth 授权。

举例来说,A 网站允许 GitHub 登录,背后就是下面的流程:

  1. A 网站让用户跳转到 GitHub。
  2. GitHub 要求用户登录,然后询问 “A 网站要求获得 XX 权限,你是否同意?”
  3. 用户同意,GitHub 就会重定向回 A 网站,同时发回一个授权码。
  4. A 网站使用授权码,向 GitHub 请求令牌。
  5. GitHub 返回令牌。
  6. 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完成功能!

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: