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

在人生的道路上,不管是潇洒走一回,或者是千山独行,皆须是自己想走的路,虽然,有的人并不是很快就能找到自己的方向和道路,不过,只要坚持到底,我相信,就一定可以找到自己的路,只要找到路,就不必怕路途遥远了。

导读:本篇文章讲解 【django】用户登录模块实现步骤(三)之QQ用户是否绑定项目用户的处理和QQ用户绑定项目用户功能实现【34】,希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com,来源:原文

一、判断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'))		

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由半码博客整理,本文链接:https://www.bmabk.com/index.php/post/123293.html

(0)
飞熊的头像飞熊bm

相关推荐

发表回复

登录后才能评论
半码博客——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!