制作一个网站的费用,php教育学校网站源码,贵州网站优化,温州建网站哪家强上一次课程#xff0c;我们了解了 OAuth 认证是怎么回事#xff0c;以及了解了四种认证方式#xff0c;今天我们将以 Github 为例#xff0c;了解一下如何用 Flask 第三方应用
在之前的介绍 JWT 的时候#xff0c;了解过 Authlib 库#xff0c;Authlib 是集 JWT、OAuth1…上一次课程我们了解了 OAuth 认证是怎么回事以及了解了四种认证方式今天我们将以 Github 为例了解一下如何用 Flask 第三方应用
在之前的介绍 JWT 的时候了解过 Authlib 库Authlib 是集 JWT、OAuth1.0、OAuth2.0 于一身的终极 Python 认证框架支持多种 Web 框架例如 Django、requests、httpx以及今天实践用的 Flask还对 Django 和 Flask 做了专门的集成让开发更简单 Github OAuth 应用是支持 OAuth2.0 协议的用授权码的模式颁发 access_token即 授权码模式authorization code 注册 github 第三方应用 首先需要去 github 上注册我们的应用注册地址: https://github.com/settings/applications/new github 应用申请注册 Homepage URL 应用的主地址这里可以填写 Flask 本地的默认地址 Authorization callback URL: 认证完成后跳转的地址可以根据项目具体情况填写 从申请配置上可以看到github 支持任意的域名不需要做额外的认证和证明这也是选择 github 做演示的原因如果要用 微信 作为认证需要申请开通开发者资质比较麻烦不过开发方式和都是类似的 申请成功后可以看到自己创建的应用配置页面: github 应用注册成功 从上图红色框的位置可以得到 client id, 和 client secret必须妥善保管
创建第三方应用 注册成功第三方应用就可以来开发客户端了
安装 Authlib
使用 pip 安装
pip install Authlib
如果一切正常可以导入 Authlib 模板例如引入 jwt : from authlib.integrations.flask_client import OAuth
创建 Web 应用
创建一个 Flask 应用:
from flask import Flask, session, render_template, url_for, redirectfrom authlib.integrations.flask_client import OAuthapp Flask(__name__)app.secret_key !secretoauth OAuth(app) 引入可能用到的 Flask 框架模块和方法 引入 Authlib 的 Flask 客户端模块 创建 Flask 应用 app 设置 应用的 secret_key, 用于做跳转认证页的校验是必须的如果缺失引导认证页会失败 用 Flask 应用实例化 OAuth
认证服务器配置
客户端需要做的是引导用户到认证页面并且能能向认证服务器请求 access_token, OAuth 实例可以从应用的配置中读取
为了简便将配置一同写入代码中实际项目中建议使用单独的配置文件后面 Flask 项目工程中会详细说明:
app.config[GITHUB_CLIENT_ID] 55ffa..省略...9e1fb3aapp.config[GITHUB_CLIENT_SECRET] 692317a38d0..省略...d63f2d9f8capp.config[GITHUB_AUTHORIZE_URL] https://github.com/login/oauth/authorizeapp.config[GITHUB_AUTHORIZE_PARAMS] { scope: user repo}app.config[GITHUB_ACCESS_TOKEN_URL] https://github.com/login/oauth/access_tokenapp.config[GITHUB_API_BASE_URL] https://api.github.com 同一个客户端应用连接多种认证服务器配置时用前缀来区分不同的认证服务器前缀随意只要同一个认证配置统一就行例如这里用的前缀是 GITHUB _CLIENT_ID、_CLIENT_SECRET注册应用成功后由认证服务器提供 _AUTHORIZE_URL用户认证页面 URL会在认证服务器文档中找到 _AUTHORIZE_PARAMS认证时提供的额外参数通常用于指定授权范围具体范围和格式参考认证服务器文档 _ACCESS_TOKEN_URL获取 access_token 的 URL _API_BASE_URL资源服务器 api 根路径具体查看资源服务器 api 文档
完成配置后创建认证服务器实例:
github oauth.register(github) register 方法会根据配置创建认证服务器实例参数同配置中的前缀大小写随意 返回认证服务器的实例也可以用 oauth.github 方式来获取认证服务器实例
设置 接入点(endpoint)
登录
app.route(/login)def login(): redirect_uri url_for(auth, _externalTrue) return github.authorize_redirect(redirect_uri) 用 url_for 函数得到 auth 视图函数的绝对访问路径参数 _external 为 True 返回绝对路径 authorize_redirect 方法接收一个 URL 作为参数即获得授权后的回调地址。注意跳转地址必须和注册时的完全一致 authorize_redirect 方法会合成带参数的认证页 URL并跳转过去
认证回跳
app.route(/auth/redirect)def auth(): token github.authorize_access_token() user github.get(user).json() 可以在此保存 token 和 用户信息例如存入数据库 session[user] user return redirect(/) 设置视图函数的接入点必须和注册时的回调保持一致Flask 的接入点建议使用 / 结尾能同时兼容不以 / 结尾请求但是这里需要与注册时的保持一致否则可能无法跳转到认证页 authorize_access_token 方法用于从认证服务器获取 access_token分装了交互细节 get 方法用户获取用户的授权资源。参数为资源服务器 api 的名称例如user、user/repos 获得用户基本信息后存入 session, 以便下次访问时获得 最后跳转到首页上 实际应用中可以在第一次获取用户信息后引导用户用手机号或者邮箱注册以便之后登录 首页
app.route(/)def homepage(): user session.get(user) return render_template(home.html, useruser) 作为演示首页很简单即从 session 中获得 user 对象将其内容显示在页面上如果 user 为空则显示登录连接 home.html 是模板具体内容参考示例代码
登出
app.route(/logout)def logout(): session.pop(user, None) return redirect(/) 登出是客户端自身的功能和认证服务器没关系只要 access_token 有效客户端就可以从资源服务器上获取用户的信息或资源 登出仅将 user 从 session 中删掉跳转到首页
刷新 access_token github OAuth app 的 access_token 是长期的不需要更新这里用 Authlib 文档中的例子作为演示 OAuth2.0 协议中的 access_token 可以设置有效期过期后需要用 refresh_token 重新获取
Authlib 提供了基于信号(类似于事件) 自动更新 access_token 的方法会在合适的时间点触发信号执行更新函数
信号机制由 blinker 库blinker 是一个简洁的为 Python 对象之间提供广播式的信号机制的库必须先安装:
pip install blinker
就不展开 blinker 了只要知道它是自动更新 access_token 需要依赖的库就行
from authlib.integrations.flask_client import token_updatetoken_update.connect_via(app)def on_token_update(sender, name, token, refresh_tokenNone, access_tokenNone): if refresh_token: item OAuth2Token.find(namename, refresh_tokenrefresh_token) elif access_token: item OAuth2Token.find(namename, access_tokenaccess_token) else: return # 更新 access_token item.access_token token[access_token] item.refresh_token token.get(refresh_token) item.expires_at token[expires_at] item.save() 先从 flask_client 包中引入 token_update 类 定义更新 access_token 的回调函数 on_token_update 通过注解 token_update.connect_via注册成监听 access_token 更新事件的回调函数 回调函数的参数 sender 是发出更新了 access_token 的实体即认证服务器实例 name 就是注册认证服务器的名称即 oauth.register 的第一个参数 token 为获得的新 access_token 对象 refresh_token 和 access_token 之前通过认证时获得的access_token 是旧的 回调函数逻辑部分通过 refresh_token 或 access_token 从查找之前的 token 记录找到后将新的 token信息更新到记录中并且保存。 OAuth2Token 可以理解成库表对象用来和库表交互维护 token 对象
小试牛刀
启动 Flask 应用
python3 app.py
访问 http://localhost:5000如果一切正常将看到页面上有个 login 连接点击此连接将跳转到认证页面登录 Github如果当前浏览器中没登录 Github 的话将看到授权页面类似于: 授权页面 http://127.0.0.1:5000 也能访问但是必须使用 http://localhost:5000 来访问即保持和注册时的首页 URL 一致 总结 本节课程演示了 Flask 基于 Authlib 完成简单认证客户端的示例是对前面 OAuth 理论的一次实践主要需要了解客户端的结构和认证流程 在认证服务器上注册客户端得到 client_id 和 client_secret 设置登录、认证后回调的接入点或叫做路由 管理获得的认证信息用认证信息获取用户授权的资源 设置刷新 access_token 的逻辑
总体来说认证客户端的实现不复杂主要是概念比较绕建议下载示例代码实践一下加深理解