【django】用户登录模块实现步骤(三)之QQ用户是否绑定项目用户的处理和QQ用户绑定项目用户功能实现【34】

本文档详细介绍了如何使用openid检查QQ用户是否已绑定芒果头条账号,已绑定则直接登录,未绑定则加密openid并传递给前端进行用户绑定操作。同时,利用itsdangerous库对openid进行签名加密和解密,确保用户隐私安全。在用户绑定过程中,实现了类似注册的逻辑,根据手机号是否存在创建或绑定项目用户,并进行状态保持。
摘要由CSDN通过智能技术生成

一、判断openid是否绑定过⽤户

使⽤openid查询该QQ⽤户是否在芒果头条中绑定过⽤户。

openid已绑定⽤户的处理:
如果openid已绑定芒果头条⽤户,直接⽣成状态保持信息,登录成功,并重定向到⾸⻚。

openid未绑定⽤户的处理:
为了能够在后续的绑定⽤户操作中前端可以使⽤openid,在这⾥将openid签名后响应给前端。
openid属于⽤户的隐私信息,所以需要将openid签名处理,避免暴露。

openid未绑定用户时,进入这个页面
在这里插入图片描述

二、itsdangerous的使⽤

安装:

pip install itsdangerous

定义utils.py文件
在这里插入图片描述
定义方法:实现对openid进行加密和对openid进行解密

from django.conf import settings
from itsdangerous import TimedJSONWebSignatureSerializer as Serializer, BadData


def generate_secret_openid(openid):
    """
    签名openid
    :param openid: 用户的openid
    :return: access_token
    """
    # 创建序列化器对象给数据加密
    serializer = Serializer(settings.SECRET_KEY,expires_in=600)
    data = {'openid': openid}
    token = serializer.dumps(data)
    return token.decode()

def check_secret_openid(sec_openid):
    """
    反解、反序列化access_token_openid
    :param access_token_openid: openid密文
    :return: openid明文
    """
    # 创建序列化器对象:序列化和反序列化的对象的参数必须是一模一样的
    s = Serializer(settings.SECRET_KEY, expires_in=600)

    # 反序列化openid密文
    try:
        data = s.loads(sec_openid)
    except BadData: # openid密文过期
        return None
    else:
        # 返回openid明文
        return data.get('openid')

三、QQ用户绑定项目用户功能实现

类似于⽤户注册的业务逻辑

当⽤户输⼊的⼿机号对应的⽤户已存在
直接将该已存在⽤户跟openid绑定。

当⽤户输⼊的⼿机号对应的⽤户不存在
新建⼀个⽤户,并跟openid绑定。

# Create your views here.
import re

import django_redis
from django.contrib.auth import login
from django.http import JsonResponse, HttpResponse
from django.shortcuts import render, redirect,reverse
from AgentLogin import AgentLogin
from django.views.generic.base import View
from django.conf import settings
from django import http

from .models import QQAuthUser

from mgproject.apps.oauth.utils import generate_secret_openid

from .utils import check_secret_openid
from userapp.models import Users


class QQLoginURLView(View):
    def get(self,request):
        '''
        获取qq扫码登陆连接地址
        :param request:
        :return:
        '''
        qq_url=AgentLogin.qq_url(client_id=settings.QQ_CLIENT_ID,redirect_url=settings.QQ_REDIRECT_URI)
        return JsonResponse({'code':200,'errormsg':'ok','login_url':qq_url})


class QQAuthUserView(View):
    def get(self,request):
        '''
        获取openis
        :param request:
        :return:
        '''
        #获取code参数
        code=request.GET.get('code','')
        #校验参数
        if not code:
            return http.HttpResponseForbidden('缺少code参数')

        #调用接口方法获取openid
        nickname,openid=AgentLogin.qq(client_id=settings.QQ_CLIENT_ID,
                                      client_secret=settings.QQ_APP_KEY,
                                      url=settings.QQ_REDIRECT_URI,
                                      code=code)

        #通过openid判断qq用户是否绑定项目用户
        try:
            qq_user=QQAuthUser.objects.get(openid=openid)
        except QQAuthUser.DoesNotExist:
            #qq用户没有绑定项目用户

            #加密openid数据
            sec_openid=generate_secret_openid(openid)
            #传递加密数据给用户绑定页面
            return render(request,'oauth/oauth_user.html',{'sec_openid':sec_openid})
        else:
            #qq用户绑定了项目用户
            #获取关联的项目用户对象
            user=qq_user.user
            #状态保持
            login(request,user)
            #响应结果
            return redirect(reverse('newsapp:index'))

    def post(self,request):
        '''
        将当前访问QQ用户绑定项目用户
        :param request:
        :return:
        '''
        #1、接收参数
        sec_openid=request.POST.get('sec_openid','')
        phone=request.POST.get('phone','')
        sms_code_client=request.POST.get('msgcode','')
        pwd=request.POST.get('password','')
        #2、校验参数
        #非空校验
        if not all([sec_openid,phone,sms_code_client,pwd]):
            return http.HttpResponseForbidden('缺少必传参数')
        #判断手机号是否合法
        if not re.match(r'^1[35789]\d{9}$', phone):
            return http.HttpResponseForbidden('请输⼊正确的⼿机号码')

        #判断密码是否合法
        if not re.match(r'^[0-9A-Za-z]{3,8}$', pwd):
            return http.HttpResponseForbidden('请输⼊3,8位的密码')

        #判断短信验证码是否一致
        redis_conn=django_redis.get_redis_connection('verify_code')
        sms_code_server=redis_conn.get('sms_%s'%phone)

        if sms_code_server is None:
            return render(request,'oauth/oauth_user.html',{'sms_code_errmg':'无效的短信验证码'})
        if sms_code_server.decode()!=sms_code_client:
            return render(request,'oauth/oauth_user.html',{'sms_code_error':'输入的短信验证码错误'})
        #3、绑定用户

        #判断当前qq用户是否合法(解密openid数据)
        openid=check_secret_openid(sec_openid)
        if not openid:
            return render(request, 'oauth/oauth_user.html', {'openid_errmg': 'openid已经实效'})
        #获取项目用户
        try:
            user=Users.objects.get(phone=phone)
        except Users.DoesNotExist:
            #创建项目新用户
            user=Users.objects.create_user(username=phone,password=pwd,phone=phone)
        else:
            #判断项目用户密码是否正确
            if not user.check_password(pwd):
                return render(request,'oauth/oauth_user.html',{'qq_login_errmsg':'用户名或者密码错误'})


        #绑定用户
        QQAuthUser.objects.create(user=user,openid=openid)

            #状态保持
        login(request,user)
        #4、返回结果
        return redirect(reverse('newsapp:index'))		
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

敲代码敲到头发茂密

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值