admin管理员组

文章数量:1530842


在实现acwing一键登录的基础上实现qq一键登录


acwing题解地址
需项目在自己的备案域名上运行

我实现好的网站地址:
http://game.ilotus.top

1、前往qq互联进行开发者资料审核

https://connect.qq/devuser.html#/create/1/
选择个人接入后填入个人信息

注:手持照片得用后置摄像头拍摄,前置摄像头有镜像功能


2、创建应用

1.在应用管理界面点击创建应用,选择创建网站应用。
2.网站名称一栏填写备案的网站名称

3.网站回调地址填写处理qq返回的请求路径

就是对应acwing一键登录中的:https://game.ilotus.top/settings/acwing/web/receive_code/

注:此处末尾不能加 /

4.填写提供方和备案号

可前往查询: https://icp.chinaz/

5.点击创建应用等待审核


3、实现代码

官方教程: https://wiki.connect.qq/%e4%bd%bf%e7%94%a8authorization_code%e8%8e%b7%e5%8f%96access_token

点击操作中的查看,可以看到APP ID 和 APP Key

1.实现views

创建文件夹 mkdir game/views/settings/qq
创建文件 touch __init__.py
创建申请code文件 vim apply_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):
    client_id = ""  # 填写 APP ID
    redirect_uri = quote("https://game.ilotus.top/settings/qq/receive_code")  # 处理网址中的特殊字符
    scope = "get_user_info"
    state = get_state()

    cache.set(state, True, 600)  # 有效期十分钟

    response_type = "code"

    apply_code_url = "https://graph.qq/oauth2.0/authorize"
    return JsonResponse({
        'result': 'success',
        'apply_code_url': apply_code_url + "?response_type=%s&client_id=%s&redirect_uri=%s&scope=%s&state=%s" % (response_type, client_id, redirect_uri, scope, state)
    })
创建接收文件 vim receive_code.py

在receive_code.py中写入以下代码

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

def receive_code(request):
    data = request.GET
    code = data.get('code')
    state = data.get('state')
    
    # 改成自己的回调地址
    redirect_uri = "https://game.ilotus.top/settings/qq/receive_code"  # 此处不用处理网址中的特殊字符

    if not cache.has_key(state):  # 若无此state返回主页面
        return redirect("index")

    cache.delete(state)


    apply_access_token_url = "https://graph.qq/oauth2.0/token"
    params = {
        'grant_type': 'authorization_code',
        'client_id': "",                     # 填入APP ID
        'client_secret': "",                 # 填入APP Key
        'code': code,
        'redirect_uri': redirect_uri,
        'fmt': "json"
    }
    access_token_res = requests.get(apply_access_token_url, params=params).json()
    access_token = access_token_res['access_token']

    apply_openid_url = "https://graph.qq/oauth2.0/me"
    params = {
        'access_token': access_token,
        'fmt': "json"
    }
    openid_res = requests.get(apply_openid_url, params=params).json()
    openid = openid_res['openid']


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


    get_user_info_url = "https://graph.qq/user/get_user_info"
    params = {
        'access_token': access_token,
        'oauth_consumer_key': "",      # 填入APP ID
        'openid': openid
    }
    userinfo_res = requests.get(get_user_info_url, params=params).json()
    username = userinfo_res['nickname']
    photo = userinfo_res['figureurl_qq_1']


    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")

2.实现urls

创建文件夹 mkdir game/urls/settings/qq
创建文件 touch __init__.py
创建路由文件 vim index.py

在index.py文件中写入以下代码

from django.urls import path
from game.views.settings.qq.apply_code import apply_code
from game.views.settings.qq.receive_code import receive_code

urlpatterns = [
    path("apply_code/", apply_code, name="settings_qq_apply_code"),
    path("receive_code", receive_code, name="settings_qq_receive_code"),
]

在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")),
    path("qq/", include("game.urls.settings.qq.index")),  # 添加这句话即可
]

3.实现前端

(1) 修改game/static/js/src/settings/zbase.js中的内容

上传qq的图标到game/static/image/settings/qq_logo.png
图标下载链接 https://game.ilotus.top/static/image/settings/qq_logo.png
官方资源库 https://wiki.connect.qq/%e8%a7%86%e8%a7%89%e7%b4%a0%e6%9d%90%e4%b8%8b%e8%bd%bd

在acwing一键登录的代码下添加上

<div class="ac-game-settings-qq">
    <img width="30" src="https://game.ilotus.top/static/image/settings/qq_logo.png">
    <br>
    <div>
        QQ一键登录
    </div>
</div>
this.$acwing_login = this.$settings.find('.ac-game-settings-acwing img')
//添加上下面这句话
this.$qq_login = this.$settings.find('.ac-game-settings-qq img')

修改监听函数,加上qq点击的事件

add_listening_events() {
    let outer = this;
    this.add_listening_events_login();
    this.add_listening_events_register();

    this.$acwing_login.click(function () {
        outer.acwing_login();
    });
    this.$qq_login.click(function () {
        outer.qq_login();
    });
}

添加上qq登录函数

qq_login() {
    var url = window.location.href;
    $.ajax({
        url: url + "settings/qq/apply_code/",
        type: "GET",
        success: function (resp) {
            if (resp.result === "success") {
                window.location.replace(resp.apply_code_url);
            }
        }
    });
}

(2) 修改game/static/css/game.css文件中的内容

修改.ac-game-settings-acwing
使得acwing一键登录靠左,给qq登录腾出空间

.ac-game-settings-acwing {
    display: block;
    height: 7vh;
    float: left;
    padding-left: 1vw;
}

添加上qq的css

.ac-game-settings-qq > img {
    position: relative;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    cursor: pointer;
}

.ac-game-settings-qq > div {
    color: white;
    font-size: 1.5vh;
    text-align: center;
    display: block;
}

.ac-game-settings-qq {
    display: block;
    height: 7vh;
    float: right;
    padding-right: 1vw;
}

完成!!!

注:记得在apply_code.py 和 receive_code.py对应位置中写入自己的APP ID 和 APP Key

本文标签: 一键qq