Django框架 (六) web端acwing一键登录

Django框架 (六) web端与acapp端acwing一键登录

1. 在Django中集成Redis

1.1 安装django_redis

pip install django_redis

1.2 配置settings.py

进入acapp/acapp/settings.py,添加:

CACHES = { 
    'default': {
        'BACKEND': 'django_redis.cache.RedisCache',
        'LOCATION': 'redis://127.0.0.1:6379/1',
        "OPTIONS": {
            "CLIENT_CLASS": "django_redis.client.DefaultClient",
        },  
    },  
}
USER_AGENTS_CACHE = 'default'

1.3 启动redis-server

sudo redis-server /etc/redis/redis.conf

1.4 django后端操控redis

python3 manage.py shell
from django.core.cache import cache

4.1查找redis数据库所有key 支持正则表达式
cache.keys("*") 查
4.2插入键值对
cache.set(‘ybz’,1,None)# None 表示存活时间为永久/s 增和改
cache.set(‘ybz’,[21,‘coding’],10)# None 表示存活时间为10s
4.3某key值是否存在
cache.has_key(‘xxx’) 查
4.4查询某个关键字的值
cache.get(‘xxx’) 查
4.5删除某个关键字
cache.delete(‘xxx’) 删

2. web端acwing一键登录

参考链接:
https://www.acwing.com/blog/content/12466/
https://www.ruanyifeng.com/blog/2019/04/oauth-grant-types.html

Django框架 (六) web端acwing一键登录_第1张图片
client web acwing
首先client端点击第三方登录

通过web服务器向acwing发送请求和appid返回授权确认界面(acwing端界面)

若用户同意授权,则acwing将授权码code发送给web服务器

web服务器接收到以后将自己的appid的appsecret以及授权码code发送给acwing 申请授权令牌

acwing发现信息没有问题,则发送给web服务器一个授权令牌 access-token和openid(用户识别码)

web服务器用授权令牌和openid发送给acwing申请用户名和头像信息

acwing发现没有问题就会返回用户名和头像给web服务器,web服务器就会保存下来 重定向到游戏界面
( web向acwing请求的code和access-token都是2个小时限制)

若不同意 不会发生重定向

2.1扩充player表的属性 openid

# 先扩充player表的属性 openid
在acapp/game/models/player的player.py加入
openid=models.CharField(default='',max_length=50,blank=True,null=True)

# 保存到数据库
python3 manage.py makemigrations
python3 manage.py migrate
    

这时可以后台查看是否增加新字段成功:
Django框架 (六) web端acwing一键登录_第2张图片

2.2 后端操作

进入acapp/game/views/settings创建acwing文件夹,同时在acwing文件夹中创建__init__.py,acapp和web文件夹

在web文件夹中创建apply_code.py与receive_code.py
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():
    res = ""
    for i in range(8):
        res += str(randint(0, 9))
    return res


def apply_code(request):
    appid = "273"
    redirect_uri = quote("https://app273.acapp.acwing.com.cn/settings/acwing/web/receive_code/")
    scope = "userinfo"
    state = get_state()

    cache.set(state, True, 7200)   # 有效期2小时

    apply_code_url = "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)
    })

receive_code.py:

from django.shortcuts import redirect
from django.core.cache import cache
import requests
from django.contrib.auth.models import User
from game.models.player.player import Player
from django.contrib.auth import login
from random import randint


def receive_code(request):
    data = request.GET
    code = data.get('code')
    state = data.get('state')

    if not cache.has_key(state):
        return redirect("index")
    cache.delete(state)

    apply_access_token_url = "https://www.acwing.com/third_party/api/oauth2/access_token/"
    params = {
        'appid': "273",
        'secret': "78d8a6dd97284e83b38bb36af115af6b",
        'code': code
    }

    access_token_res = requests.get(apply_access_token_url, params=params).json()

    access_token = access_token_res['access_token']
    openid = access_token_res['openid']

    players = Player.objects.filter(openid=openid)
    if players.exists():  # 如果该用户已存在,则无需重新获取信息,直接登录即可
        login(request, players[0].user)
        return redirect("index")

    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():  # 找到一个新用户名
        username += str(randint(0, 9))

    user = User.objects.create(username=username)
    player = Player.objects.create(user=user, photo=photo, openid=openid)

    login(request, user)

    return redirect("index")

更新urls:
进入acapp/game/urls/settings/acwing/index.py
index.py:

from django.urls import path
from game.views.settings.acwing.web.apply_code import apply_code
from game.views.settings.acwing.web.receive_code import receive_code


urlpatterns = [
    path("web/apply_code/", apply_code, name="settings_acwing_web_apply_code"),
    path("web/receive_code/", receive_code, name="settings_acwing_web_receive_code"),
]

总的settings的index:
acapp/game/urls/settings/index.py

from django.urls import path, include
from game.views.settings.getinfo import getinfo
from game.views.settings.login import signin
from game.views.settings.logout import signout
from game.views.settings.register import register


urlpatterns = [
    path("getinfo/", getinfo, name="settings_getinfo"),
    path("login/", signin, name="settings_login"),
    path("logout/", signout, name="settings_logout"),
    path("register/", register, name="settings_register"),
    path("acwing/", include("game.urls.settings.acwing.index")),
]

修复之前getinfo.py中的bug:
acapp/game/views/settings/getinfo.py

from django.http import JsonResponse
from game.models.player.player import Player

def getinfo_acapp(request):
    player = Player.objects.all()[0]
    return JsonResponse({
        'result': "success",
        'username': player.user.username,
        'photo': player.photo,
    })

def getinfo_web(request):
    user = request.user
    if not user.is_authenticated:
        return JsonResponse({
            'result': "未登录"
        })
    else:
        player = Player.objects.get(user=user)
        return JsonResponse({
            'result': "success",
            'username': player.user.username,
            'photo': player.photo,
        })

def getinfo(request):
    platform = request.GET.get('platform')
    if platform == "ACAPP":
        return getinfo_acapp(request)
    elif platform == "WEB":
        return getinfo_web(request)

2.3 前端操作

更改acapp/game/static/js/src/settings/zbase.js

class Settings {
    constructor(root) {
        this.root = root;
        this.platform = "WEB";
        if (this.root.AcWingOS) this.platform = "ACAPP";
        this.username = "";
        this.photo = "";

        this.$settings = $(`
注册
登录


AcWing一键登录
`
); this.$login = this.$settings.find(".ac-game-settings-login"); this.$login_username = this.$login.find(".ac-game-settings-username input"); this.$login_password = this.$login.find(".ac-game-settings-password input"); this.$login_submit = this.$login.find(".ac-game-settings-submit button"); this.$login_error_message = this.$login.find(".ac-game-settings-error-message"); this.$login_register = this.$login.find(".ac-game-settings-option"); this.$login.hide(); this.$register = this.$settings.find(".ac-game-settings-register"); this.$register_username = this.$register.find(".ac-game-settings-username input"); this.$register_password = this.$register.find(".ac-game-settings-password-first input"); this.$register_password_confirm = this.$register.find(".ac-game-settings-password-second input"); this.$register_submit = this.$register.find(".ac-game-settings-submit button"); this.$register_error_message = this.$register.find(".ac-game-settings-error-message"); this.$register_login = this.$register.find(".ac-game-settings-option"); this.$register.hide(); //新增 this.$acwing_login = this.$settings.find('.ac-game-settings-acwing img'); this.root.$ac_game.append(this.$settings); this.start(); } start() { this.getinfo(); this.add_listening_events(); } add_listening_events() { let outer = this; this.add_listening_events_login(); this.add_listening_events_register(); this.$acwing_login.click(function() { outer.acwing_login(); }); } add_listening_events_login() { let outer = this; this.$login_register.click(function() { outer.register(); }); this.$login_submit.click(function() { outer.login_on_remote(); }); } add_listening_events_register() { let outer = this; this.$register_login.click(function() { outer.login(); }); this.$register_submit.click(function() { outer.register_on_remote(); }); } //新增 acwing_login() { $.ajax({ url: "https://app273.acapp.acwing.com.cn/settings/acwing/web/apply_code/", type: "GET", success: function(resp) { console.log(resp); if (resp.result === "success") { window.location.replace(resp.apply_code_url); } } }); } login_on_remote() { // 在远程服务器上登录 let outer = this; let username = this.$login_username.val(); let password = this.$login_password.val(); this.$login_error_message.empty(); $.ajax({ url: "https://app273.acapp.acwing.com.cn/settings/login/", type: "GET", data: { username: username, password: password, }, success: function(resp) { console.log(resp); if (resp.result === "success") { location.reload(); } else { outer.$login_error_message.html(resp.result); } } }); } register_on_remote() { // 在远程服务器上注册 let outer = this; let username = this.$register_username.val(); let password = this.$register_password.val(); let password_confirm = this.$register_password_confirm.val(); this.$register_error_message.empty(); $.ajax({ url: "https://app273.acapp.acwing.com.cn/settings/register/", type: "GET", data: { username: username, password: password, password_confirm: password_confirm, }, success: function(resp) { console.log(resp); if (resp.result === "success") { location.reload(); // 刷新页面 } else { outer.$register_error_message.html(resp.result); } } }); } logout_on_remote() { // 在远程服务器上登出 if (this.platform === "ACAPP") return false; $.ajax({ url: "https://app273.acapp.acwing.com.cn/settings/logout/", type: "GET", success: function(resp) { console.log(resp); if (resp.result === "success") { location.reload(); } } }); } register() { // 打开注册界面 this.$login.hide(); this.$register.show(); } login() { // 打开登录界面 this.$register.hide(); this.$login.show(); } getinfo() { let outer = this; $.ajax({ url: "https://app273.acapp.acwing.com.cn/settings/getinfo/", type: "GET", data: { platform: outer.platform, }, success: function(resp) { console.log(resp); if (resp.result === "success") { outer.username = resp.username; outer.photo = resp.photo; outer.hide(); outer.root.menu.show(); } else { outer.login(); } } }); } hide() { this.$settings.hide(); } show() { this.$settings.show(); } }

注意更改js一定是要在acapp/game/static,而不是在acapp/static里操作,否则打包程序打包无效。

3.acapp端acwing一键登录

Django框架 (六) web端acwing一键登录_第3张图片

3.1后端操作

进入acapp/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():
    res = ""
    for i in range(8):
        res += str(randint(0, 9))
    return res


def apply_code(request):
    appid = "273"
    redirect_uri = quote("https://app273.acapp.acwing.com.cn/settings/acwing/acapp/receive_code/")
    scope = "userinfo"
    state = get_state()

    cache.set(state, True, 7200)   # 有效期2小时

    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):
    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):
        return JsonResponse({
            'result': "state not exist"
        })
    cache.delete(state)

    apply_access_token_url = "https://www.acwing.com/third_party/api/oauth2/access_token/"
    params = {
        'appid': "273",
        'secret': "19f22bef139b44079d1905d6a78f6ca9",
        'code': code
    }

    access_token_res = requests.get(apply_access_token_url, params=params).json()

    access_token = access_token_res['access_token']
    openid = access_token_res['openid']

    players = Player.objects.filter(openid=openid)
    if players.exists():  # 如果该用户已存在,则无需重新获取信息,直接登录即可
        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():  # 找到一个新用户名
        username += str(randint(0, 9))

    user = User.objects.create(username=username)
    player = Player.objects.create(user=user, photo=photo, openid=openid)

    return JsonResponse({
        'result': "success",
        'username': player.user.username,
        'photo': player.photo,
    })

更新urls:
进入acapp/game/urls/settings/acwing/index.py
index.py:

from django.urls import path
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"),
]

3.2 前端操作

更改acapp/game/static/js/src/settings/zbase.js

class Settings {
    constructor(root) {
        this.root = root;
        this.platform = "WEB";
        if (this.root.AcWingOS) this.platform = "ACAPP";
        this.username = "";
        this.photo = "";

        this.$settings = $(`
注册
登录


AcWing一键登录
`
); this.$login = this.$settings.find(".ac-game-settings-login"); this.$login_username = this.$login.find(".ac-game-settings-username input"); this.$login_password = this.$login.find(".ac-game-settings-password input"); this.$login_submit = this.$login.find(".ac-game-settings-submit button"); this.$login_error_message = this.$login.find(".ac-game-settings-error-message"); this.$login_register = this.$login.find(".ac-game-settings-option"); this.$login.hide(); this.$register = this.$settings.find(".ac-game-settings-register"); this.$register_username = this.$register.find(".ac-game-settings-username input"); this.$register_password = this.$register.find(".ac-game-settings-password-first input"); this.$register_password_confirm = this.$register.find(".ac-game-settings-password-second input"); this.$register_submit = this.$register.find(".ac-game-settings-submit button"); this.$register_error_message = this.$register.find(".ac-game-settings-error-message"); this.$register_login = this.$register.find(".ac-game-settings-option"); this.$register.hide(); this.$acwing_login = this.$settings.find('.ac-game-settings-acwing img'); this.root.$ac_game.append(this.$settings); this.start(); } start() { if (this.platform === "ACAPP") { this.getinfo_acapp(); } else { this.getinfo_web(); this.add_listening_events(); } } add_listening_events() { let outer = this; this.add_listening_events_login(); this.add_listening_events_register(); this.$acwing_login.click(function() { outer.acwing_login(); }); } add_listening_events_login() { let outer = this; this.$login_register.click(function() { outer.register(); }); this.$login_submit.click(function() { outer.login_on_remote(); }); } add_listening_events_register() { let outer = this; this.$register_login.click(function() { outer.login(); }); this.$register_submit.click(function() { outer.register_on_remote(); }); } acwing_login() { $.ajax({ url: "https://app273.acapp.acwing.com.cn/settings/acwing/web/apply_code/", type: "GET", success: function(resp) { console.log(resp); if (resp.result === "success") { window.location.replace(resp.apply_code_url); } } }); } login_on_remote() { // 在远程服务器上登录 let outer = this; let username = this.$login_username.val(); let password = this.$login_password.val(); this.$login_error_message.empty(); $.ajax({ url: "https://app273.acapp.acwing.com.cn/settings/login/", type: "GET", data: { username: username, password: password, }, success: function(resp) { console.log(resp); if (resp.result === "success") { location.reload(); } else { outer.$login_error_message.html(resp.result); } } }); } register_on_remote() { // 在远程服务器上注册 let outer = this; let username = this.$register_username.val(); let password = this.$register_password.val(); let password_confirm = this.$register_password_confirm.val(); this.$register_error_message.empty(); $.ajax({ url: "https://app273.acapp.acwing.com.cn/settings/register/", type: "GET", data: { username: username, password: password, password_confirm: password_confirm, }, success: function(resp) { console.log(resp); if (resp.result === "success") { location.reload(); // 刷新页面 } else { outer.$register_error_message.html(resp.result); } } }); } logout_on_remote() { // 在远程服务器上登出 if (this.platform === "ACAPP") return false; $.ajax({ url: "https://app273.acapp.acwing.com.cn/settings/logout/", type: "GET", success: function(resp) { console.log(resp); if (resp.result === "success") { location.reload(); } } }); } register() { // 打开注册界面 this.$login.hide(); this.$register.show(); } login() { // 打开登录界面 this.$register.hide(); this.$login.show(); } 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() { let outer = this; $.ajax({ url: "https://app273.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); } } }); } getinfo_web() { let outer = this; $.ajax({ url: "https://app273.acapp.acwing.com.cn/settings/getinfo/", type: "GET", data: { platform: outer.platform, }, success: function(resp) { console.log(resp); if (resp.result === "success") { outer.username = resp.username; outer.photo = resp.photo; outer.hide(); outer.root.menu.show(); } else { outer.login(); } } }); } hide() { this.$settings.hide(); } show() { this.$settings.show(); } }

你可能感兴趣的:(Django,密度分析,arcgis,django)