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

用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完成功能!

  • 4
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值