Django 框架课
6.创建用户系统
6.3 实现AcApp端一键登录
实现原理跟上一节课是一样的。只不过申请授权码的方式不一样,上一节课的方法是通过URL申请的,这一节课的方法是通过API来申请的。
首先进入game/views/settings/acwing/acapp/apply_code.py
,实现申请授权码代码跟上一节课的基本相似,所以先直接复制,再进行修改。
from django.http import JsonResponse
from urllib.parse import quote # 引入用于将链接转换为某种格式的工具,把特殊字符比如空格等换成别的表示方式
from random import randint # 引入用于生成随机数的
from django.core.cache import cache
def get_state(): # 获取8位随机数
res = ""
for i in range(8):
res += str(randint(0, 9))
return res
def apply_code(request):
appid = "23"
redirect_uri = quote("https://app23.acapp.acwing.com.cn/settings/acwing/acapp/receive_code/")
scope = "userinfo"
state = get_state()
cache.set(state, True, 7200)
# apply_url_code = "https://www.acwing.com/third_party/api/oauth2/web/authorize/"
return JsonResponse({
'result': "success",
# 'apply_code_url' = apply_code_url + "?appid=%s&redirect_uri=%s&scope=%s&state=%s" % (appid, redirect_uri, scope, state)
# 只要返回这4个参数就行了
'appid': appid,
'redirect_uri': redirect_uri,
'scope': scope,
'state': state,
})
然后再写一下路由,进入game/urls/settings/acwing/index.py
,加两个路由,同时解决一下命名冲突。
from game.views.settings.acwing.web.apply_code import apply_code as web_apply_code
from game.views.settings.acwing.web.receive_code import receive_code as web_receive_code
from game.views.settings.acwing.acapp.apply_code import apply_code as acapp_apply_code
from game.views.settings.acwing.acapp.receive_code import receive_code as acapp_receive_code
urlpatterns = [
path("web/apply_code/", web_apply_code, name = "settings_acwing_web_apply_code"),
path("web/receive_code/", web_receive_code, name = "settings_acwing_web_receive_code"),
path("acapp/apply_code/", acapp_apply_code, name = "settings_acwing_acapp_apply_code"),
path("acapp/receive_code", acapp_receive_code, name = "settings_acwing_acapp_receive_code"),
]
然后进入前端实现这个功能,进入class Settings
。如果是在Web
端登录要进行getinfo()
,如果是在acapp
端登录,需要单独写一个getinfo_acapp()
。
start()
{
if (this.platform === "ACAPP") // 如果是在ACAPP端登录
{
this.getinfo_acapp();
}
else
{
this.getinfo_web();
this.add_listening_events(); // 这些监听都是那些登陆注册页面那些元素才需要监听,ACAPP直接登录不需要这些页面
}
}
getinfo_web() // 原来的getinfo()
{
...;
}
getinfo_acapp()
{
let outer = this;
$.ajax({
url: "https://app23.acapp.acwing.com.cn/settings/acwing/acapp/apply_code/", // acapp端申请授权码
type: "GET",
success: function(resp){
if (resp.result === "success")
{
outer.acapp_login(resp.appid, resp.redirect_uri, resp.scope, resp.state); // 调用acapp端的登录
}
}
})
}
acapp_login(appid, redirect_uri, scope, state)
{
let outer = this;
this.root.OS.api.oauth2.authorize(appid, redirect_uri, scope, state, function(resp){ // 照抄讲义上的,调用api,最后一个参数是返回之后调用的函数
console.log(resp); // 测试
if (resp.result === "success")
{
outer.username = resp.username;
outer.photo = resp.photo;
outer.hide();
outer.root.menu.show();
}
});
}
我们还要注意后端的game/views/settings/acwing/acapp/receive_code
,如果用户拒绝了就会返回一个错误码,要再考虑上这个情况。
def receive_code(request):
data = request.GET
if "errcode" in data:
return JsonResponse({
'result': "apply failed",
'errcode': data['errcode'],
'errmsg': data['errmsg'],
})
# ...
if not cache.has_key(state):
return JsonResponse({
'result': "state not exist",
})
# ...
if players.exists():
# login(...) # 这个是只在浏览器上的settings登录的,我们在acapp的云端上直接登录,不需要每次都登录,更安全。
player = players[0]
return JsonResponse({
'result': "success",
'username': player.user.username,
'photo': player.photo
})
# ...
# login(...)
return JsonResponse({
'result': "success",
'username': player.user.username,
'photo': player.photo
})
至此,本节课任务完成。
点赞
this.root.OS.api.oauth2.authorize(appid, redirect_uri, scope, state, function(resp)改成this.root.AcWingOS.api.oauth2.authorize