前一节:WEB端AcWing授权登录(详细操作步骤)https://www.acwing.com/blog/content/33541/
AcWing 授权登录的流程
ACAPP 授权登录和 WEB 端流程是一样的,只是某些具体的实现细节有所区别。
AcWing API 文档:https://www.acwing.com/blog/content/12467/
apply_code.py
:返回给客户端 5 个参数。
from django.http import JsonResponse
from urllib.parse import quote
from random import randint
from django.core.cache import cache
def get_state():
res = ""
for i in range(8):
res += str(randint(0, 9))
return res
def apply_code(request):
appid = "2306"
redirect_uri = quote("https://app2306.acapp.acwing.com.cn/settings/acwing/acapp/receive_code") # recode for url, replace special char, eg: ':、?、&' etc.
scope = "userinfo"
state = get_state() # generate a 8bit random string, avoid other user attack our website
cache.set(state, True, 7200) # state expire time 2h
return JsonResponse({
'result': "success",
'appid': appid,
'redirect_uri': redirect_uri,
'scope': scope,
'state': state,
})
receive_code.py
:接受授权码的地址处理函数
from django.http import JsonResponse
from django.core.cache import cache
import requests
from django.contrib.auth.models import User
from game.models.player.player import Player
from random import randint
def receive_code(request): # 接受授权码的地址 | receive code address
data = request.GET
if "errcode" in data: # 如果用户拒绝授权直接返回错误信息
return JsonResponse({
'result': "apply failed",
'errcode': data['errcode'],
'errmsg': data['errmsg'],
})
code = data.get('code')
state = data.get('state')
if not cache.has_key(state): # 如果 state 参数不存在直接返回 JsonResponse 信息 | if the request state is not exist in redis, retu
rn JsonResponse
return JsonResponse({
'result': "state not exist"
})
# after authenticate success
cache.delete(state) # delete state key, guarantee one state for one authenticate
apply_access_token_url = "https://www.acwing.com/third_party/api/oauth2/access_token/"
params = {
'appid': "2306",
'secret': "d65441100a02403cb939989e688178c8",
'code': code
}
access_token_res = requests.get(apply_access_token_url, params).json() # send a get request to url use requests lib
access_token = access_token_res['access_token']
openid = access_token_res['openid']
players = Player.objects.filter(openid=openid)
if players.exists(): # 如果该用户已存在,则无需从 AcWing 重新获取用户信息,直接登录即可 | if the user already exists, you dont need to get the user info from acwing again, just login.
# login(request, players[0].user) # acapp 不需要登录,只在 web 端起作用
player = players[0]
return JsonResponse({
'result': "success",
'username': player.user.username,
'photo': player.photo
})
get_userinfo_url = "https://www.acwing.com/third_party/api/meta/identity/getinfo/"
params = {
"access_token": access_token,
"openid": openid,
}
userinfo_res = requests.get(get_userinfo_url, params=params).json();
username = userinfo_res['username']
photo = userinfo_res['photo']
while User.objects.filter(username=username).exists(): # get a not existed username
username += str(randint(0, 9))
user = User.objects.create(username=username) # create user and save db
player = Player.objects.create(user=user, photo=photo, openid=openid) # create player and save db
# login(request, user)
return JsonResponse({
'result': "success",
'username': player.user.username,
'photo': player.photo
})
配置路由,后端接口调试通过后,开始写 acapp 前端 js 逻辑 settings/zbase.js
,核心代码实现和修改。
start() {
if (this.platform === "ACAPP") {
this.getinfo_acapp();
} else {
this.getinfo_web();
this.add_listening_events();
}
}
...
acapp_login(appid, redirect_uri, scope, state) {
let outer = this;
this.root.AcWingOS.api.oauth2.authorize(appid, redirect_uri, scope, state, function(resp) {
console.log("called from acapp_login function");
console.log(resp);
if (resp.result === "success") { // 授权成功获取用户名头像
outer.username = resp.username;
outer.photo = resp.photo;
outer.hide();
outer.root.menu.show();
}
});
}
...
getinfo_acapp() { // 直接从后台获取授权登录的四个参数信息 | get authenticate login params from server
let outer = this;
$.ajax({
url: "https://app2306.acapp.acwing.com.cn/settings/acwing/acapp/apply_code/",
type: "GET",
success: function(resp) {
if (resp.result === "success") { // 获取成功,发起授权
outer.acapp_login(resp.appid, resp.redirect_uri, resp.scope, resp.state);
}
}
});
}
实现效果
点击打开 acapp 应用后的实现效果:默认打开 acwing 授权窗口,点击同意后进入菜单页面。