Oauth2授权实践(acwing一键登录)
修改用户数据表
修改model文件
- 增加openid字段
更新数据库
- 执行
python3 manage.py makemigrations
- 执行
python3 manage.py migrate
检测修改
重启服务,登进/admin,查看,修改成功
申请授权码code
请求地址:https://www.acwing.com/third_party/api/oauth2/web/authorize/[HTML_REMOVED]参考示例:
请求方法:GET
https://www.acwing.com/third_party/api/oauth2/web/authorize/?appid=APPID&redirect_uri=REDIRECT_URI&scope=SCOPE&state=STATE
参数说明
参数 | 是否必须 | 说明 |
---|---|---|
appid | 是 | 应用的唯一id,可以在AcWing编辑AcApp的界面里看到 |
redirect_uri | 是 | 接收授权码的地址。需要用urllib.parse.quote 对链接进行处理 |
scope | 是 | 申请授权的范围。目前只需填userinfo |
state | 否 | 用于判断请求和回调的一致性,授权成功后后原样返回。该参数可用于防止csrf攻击(跨站请求伪造攻击),建议第三方带上该参数,可设置为简单的随机数 |
返回说明
用户同意授权后会重定向到redirect_uri
,返回参数为code
和state
。链接格式如下:[HTML_REMOVED]`redirect_uri?code=CODE&state=STATE``[HTML_REMOVED]如果用户拒绝授权,则不会发生重定向。
[HTML_REMOVED]
创建文件夹
创建python文件
编写与文件名同名函数,实现先写pass
配置路由
- /acapp/game/urls/settings/index.py
- /acapp/game/urls/settings/acwing/index.py
quote
对重定向链接处理
- 试用
- 可将链接中的特殊字符换为非特殊字符
实现apply_code.py
- 按照规范的参数进行返回
前端跳转
- 获取页面图标dom节点
- 注册事件
- 实现函数
申请授权令牌access_token
和用户的openid
请求地址:[https://www.acwing.com/third_party/api/oauth2/access_token/](https://www.acwing.com/third_party/api/oauth2/access_token/)
参考示例:
请求方法:GET
https://www.acwing.com/third_party/api/oauth2/access_token/?appid=APPID&secret=APPSECRET&code=CODE
参数说明
参数 | 是否必须 | 说明 |
---|---|---|
appid | 是 | 应用的唯一id,可以在AcWing编辑AcApp的界面里看到 |
secret | 是 | 应用的秘钥,可以在AcWing编辑AcApp的界面里看到 |
code | 是 | 第一步中获取的授权码 |
返回说明
申请成功示例:
{
"access_token": "ACCESS_TOKEN",
"expires_in": 7200,
"refresh_token": "REFRESH_TOKEN",
"openid": "OPENID",
"scope": "SCOPE",
}
申请失败示例:
{
"errcode": 40001,
"errmsg": "code expired", # 授权码过期
}
返回参数说明
参数 | 说明 |
---|---|
access_token | 授权令牌,有效期2小时 |
expires_in | 授权令牌还有多久过期,单位(秒) |
refresh_token | 用于刷新access_token的令牌,有效期30天 |
openid | 用户的id。每个AcWing用户在每个acapp中授权的openid是唯一的,可用于识别用户。 |
scope | 用户授权的范围。目前范围为userinfo,包括用户名、头像 |
刷新access_token的有效期[HTML_REMOVED]access_token
的有效期为2小时,时间较短。[HTML_REMOVED]refresh_token
的有效期为30天,可用于刷新access_token
[HTML_REMOVED]刷新结果有两种:
- 如果
access_token
已过期,则生成一个新的access_token
- 如果
access_token
未过期,则将当前的access_token
的有效期延长为2小时。
参考示例:
请求方法:GET
https://www.acwing.com/third_party/api/oauth2/refresh_token/?appid=APPID&refresh_token=REFRESH_TOKEN
返回结果的格式与申请access_token
相同。
实现receive_code函数
- 检测state是否有效
- 向acwing发送请求,获得
access_token_res
(含有授权令牌)
申请用户信息
请求地址:[https://www.acwing.com/third_party/api/meta/identity/getinfo/](https://www.acwing.com/third_party/api/meta/identity/getinfo/)
[HTML_REMOVED]参考示例:
请求方法:GET
https://www.acwing.com/third_party/api/meta/identity/getinfo/?access_token=ACCESS_TOKEN&openid=OPENID
参数说明
参数 | 是否必须 | 说明 |
---|---|---|
access_token | 是 | 第二步中获取的授权令牌 |
openid | 是 | 第二步中获取的用户openid |
返回说明
申请成功示例
{
'username': "USERNAME",
'photo': "https:cdn.acwing.com/xxxxx"
}
申请失败示例:
{
'errcode': "40004",
'errmsg': "access_token expired" # 授权令牌过期
}
读取授权令牌和openid
判断openid账号是否已注册
请求用户信息