Django--QQ登录

定义 QQ 登录模型类

1. 定义模型类基类

在内层 meiduo_mall 中 添加新的包 utils

在这个包中增加 BaseModel.py 文件.

在这个文件里,添加如下的代码,这里的代码主要作为别的模型类的基类来使用.

增加数据新建时间和更新时间:
from django.db import models

class BaseModel(models.Model):
    """为模型类补充字段"""

    # 创建时间: 
    create_time = models.DateTimeField(auto_now_add=True,verbose_name="创建时间")
     更新时间: 
    update_time = models.DateTimeField(auto_now=更新时间)

     Meta:
         说明是抽象模型类(抽象模型类不会创建表)
        abstract = True
上面代码中相关参数解读:

auto_now_add:

创建或添加对象时自动添加时间,修改或更新对象时,不会更改时间

auto_now:

凡是对对象进行操作(创建/添加/修改/更新),时间都会随之改变

abstract:

声明该模型类仅继承使用,数据库迁移时不会创建 BaseModel 的表

2. 定义 QQ 需要使用的登录模型类

在 oauth.models.py 中添加如下模型类,用于存放 user 和 openid:

 导入: 
 models
from meiduo_mall.utils.BaseModel  BaseModel

 定义QQ登录的模型类: 
 OAuthQQUser(BaseModel):
    QQ登录用户数据 user 是个外键,关联对应的用户
    user = models.ForeignKey('users.User',on_delete=models.CASCADE,1)">用户 qq 发布的用户身份id
    openid = models.CharField(max_length=64openidTrue)

     Meta:
        db_table = tb_oauth_qq
        verbose_name = 
        verbose_name_plural = verbose_name

QQLoginTool 使用说明

1. 导入

 使用时,需要导入该包:
# 我们可以从下载的 QQLoginTool 中导入 OAuthQQ:
from QQLoginTool.QQtool import OAuthQQ

2. 初始化 OAuthQQ 对象

 创建对象 创建对象的时候,需要传递四个参数: 
oauth = OAuthQQ(client_id=settings.QQ_CLIENT_ID,client_secret=settings.QQ_CLIENT_SECRET,redirect_uri=settings.QQ_REDIRECT_URI,state=next)
相关参数解读:

client_id: 在 QQ 互联申请到的客户端 id

client_secret: 我们申请的客户端秘钥

redirect_uri: 我们申请时添加的: 登录成功后回调的路径

state: 就是我们之前接收的 next 参数

3. 对象提供的方法一: 获取 QQ 地址.

获取 QQ 登录扫码页面,扫码后得到 Authorization Code( 特许码 )

 调用对象的 get_qq_url() 函数,获取对应的扫码页面: 
login_url = oauth.get_qq_url()

4. 对象提供的方法二: 获取 QQ 的 access_token.

通过上面一个函数获取的 Authorization Code 再获取 Access Token

 调用对象的方法,根据 code 获取 access_token: 
access_token = oauth.get_access_token(code)

5. 对象提供的方法二: 获取 QQ 的 access_token.

通过上面一个函数获取的 Access Token 再获取 OpenID

QQ 登录接口的制定

获取 QQ 登录扫码页面接口

 OAuthQQ
from django.conf  settings
from django  http
from django.views  View


 QQFirstView(View):
    提供QQ登录页面网址def get(self,request):
         next 表示从哪个页面进入到的登录页面
         将来登录成功后,就自动回到那个页面
        next = request.GET.get(next)

         获取 QQ 登录页面网址
         创建 OAuthQQ 类的对象
        oauth = OAuthQQ(client_id=next)

         调用对象的获取 qq 地址方法
        login_url = oauth.get_qq_url()

         返回登录地址
        return JsonResponse({code: 0,errmsg': OKlogin_url':login_url})

QQ 登录参数

 QQ登录参数 我们申请的 客户端id
QQ_CLIENT_ID = 101474184'
 我们申请的 客户端秘钥
QQ_CLIENT_SECRET = c6ce949e04e12ecc909ae6a8b09b637c 我们申请时添加的: 登录成功后回调的路径
QQ_REDIRECT_URI = http://www.meiduo.site:8080/oauth_callback.html'

添加子路由

 获取 QQ 扫码登录链接
re_path(r^qq/authorization/$',views.QQFirstView.as_view()),

 第二个接口

from oauth.models  OAuthQQUser
 logging
logger = logging.getLogger(django)
from django.contrib.auth  login
from oauth.utils  generate_access_token

 QQUserView(View):
    用户扫码登录的回调处理Oauth2.0认证"""
         获取前端发送过来的 code 参数: 
        code = request.GET.get(if not code:
             判断 code 参数是否存在
            return http.JsonResponse({': 400缺少code参数})

         调用我们安装的 QQLoginTool 工具类
         创建工具对象
        oauth = OAuthQQ(client_id=settings.QQ_REDIRECT_URI)

        try:
             携带 code 向 QQ服务器 请求 access_token
            access_token = oauth.get_access_token(code)

             携带 access_token 向 QQ服务器 请求 openid
            openid = oauth.get_open_id(access_token)

        except Exception as e:
             如果上面获取 openid 出错,则验证失败
            logger.error(e)
             返回结果
            oauth2.0认证失败,即获取qq信息失败})
        pass

给上面的接口增加子路由:

 QQ用户部分接口: 
re_path(r^oauth_callback/$openid 是否绑定用户的处理

判断 openid 是否绑定过用户

使用 openid 查询该 QQ 用户是否在美多商城中绑定过用户。

:
    oauth_qq = OAuthQQUser.objects.get(openid=openid)
 Exception as e:
     如果 openid 没绑定美多商城用户
    pass
else:
     如果 openid 已绑定美多商城用户
    pass

openid 已绑定用户的处理

如果 openid 已绑定美多商城用户

直接生成状态保持信息,登录成功,并重定向到首页。

 查看是否有 openid 对应的用户
    oauth_qq = OAuthQQUser.objects.get(openid=openid)

 请查看:  openid 未绑定用户的处理
     根据 user 外键,获取对应的 QQ 用户(user)
    user = oauth_qq.user

      实现状态保持
    login(request,user)

     创建重定向到主页的对象
    response = JsonResponse({:0,1)">':ok})

     将用户信息写入到 cookie 中,有效期14天
    response.set_cookie(username 返回响应
    return response

openid 未绑定用户的处理

为了能够在后续的绑定用户操作中前端可以使用 openid,

在这里将 openid 签名后响应给前端。

openid 属于用户的隐私信息,所以需要将 openid 签名处理,避免暴露。

 如果 openid 没绑定美多商城用户,进入这里: 

     调用我们自定义的方法,对 openid 进行加密
     把 openid 变为 access_token
    access_token = generate_access_token(openid)

     把 access_token 返回给前端
     注意: 这里一定不能返回 0 的状态码. 否则不能进行绑定页面
    ':300access_token:access_token})
:
    ...

补充 itsdangerous 的使用

from itsdangerous  TimedJSONWebSignatureSerializer
 settings

 generate_access_token(openid):
    对传入的 openid 进行加密处理,返回 token"""

         QQ 登录保存用户数据的 token 有效期
     settings.SECRET_KEY: 加密使用的秘钥
     过期时间: 600s = 10min
    serializer = TimedJSONWebSignatureSerializer(settings.SECRET_KEY,expires_in=600)
    data = {: openid}

     对 dict 进行加密
    token = serializer.dumps(data)

     加密完之后,解码返回.
    return token.decode()

绑定用户接口实现

 

 

 Oauth2.0 认证"""
        ......

     post(self,1)">美多商城用户绑定到openid 1.接收参数
        dict = json.loads(request.body.decode())
        mobile = dict.get(mobile)
        password = dict.get(password)
        sms_code_client = dict.get(sms_code)
        access_token = dict.get( 2.校验参数
         判断参数是否齐全
         all([mobile,password,sms_code_client]):
            ':400缺少必传参数 判断手机号是否合法
        not re.match(r^1[3-9]\d{9}$请输入正确的手机号码})


         判断密码是否合格
        ^[0-9A-Za-z]{8,20}$请输入8-20位的密码 3.判断短信验证码是否一致
         创建 redis 链接对象:
        redis_conn = get_redis_connection(verify_code 从 redis 中获取 sms_code 值:
        sms_code_server = redis_conn.get(sms_%s' % mobile)

         判断获取出来的有没有: 
        if sms_code_server is None:
             如果没有,直接返回: 
            验证码失效 如果有,则进行判断: 
        if sms_code_client != sms_code_server.decode():
             如果不匹配,则直接返回: 
            输入的验证码有误})  

         调用我们自定义的函数,检验传入的 access_token 是否正确:
         错误提示放在 sms_code_errmsg 位置
        openid = check_access_token(access_token)
         openid:
            缺少openid 4.保存注册数据
        :
            user = User.objects.get(mobile=mobile)
         用户不存在,新建用户
            user = User.objects.create_user(username=mobile,password=password,mobile= 如果用户存在,检查用户密码
             user.check_password(password):
               输入的密码不正确 5.将用户绑定 openid
        :
            OAuthQQUser.objects.create(openid=openid,user=user)
        往数据库添加数据出错 6.实现状态保持
        login(request,user)

         7.创建响应对象: 
        response = JsonResponse({ 8.登录时用户名写入到 cookie,有效期14天
        response.set_cookie( 9.响应
        return response
 BadData


 定义函数,检验传入的 access_token 里面是否包含有 openid
 check_access_token(access_token):
    
    检验用户传入的 token
    :param token: token
    :return: openid or None
     调用 itsdangerous 中的类,生成对象
    serializer =:
            尝试使用对象的 loads 函数
            对 access_token 进行反序列化( 类似于解密 )
        查看是否能够获取到数据:
       data = serializer.loads(access_token)

     BadData:
         如果出错,则说明 access_token 里面不是我们认可的. 
         返回 None
        return None
    :
         如果能够从中获取 data,则把 data 中的 openid 返回
        return data.get(')

 

原文地址:https://www.cnblogs.com/tracydzf

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

相关推荐


注:所有源代码均实测运行过。所有源代码均已上传CSDN,请有需要的朋友自行下载。
继承APIView和ViewSetMixin;作用也与APIView基本类似,提供了身份认证、权限校验、流量管理等。ViewSet在开发接口中不经常用。
一、Django介绍Python下有许多款不同的 Web 框架。Django是重量级选手中最有代表性的一位。许多成功的网站和APP都基于Django。Django 是一个开放源代码的 Web 应用框架,由 Python 写成。Django 遵守 BSD 版权,初次发布于 2005 年 7 月, 并于 2008 年 9 月发布了第一个正式版本 1.0 。Django学习线路Django 采用了 MVT 的软件设计模式,即模型(Model),视图(View)和模板(Template)。这个MVT模式并
本文从nginx快速掌握到使用,gunicorn快速掌握到使用,实现小白快速搭建django项目,并对可能出现的报错进行了分析
uniapp微信小程序订阅消息发送服务通知
Django终端打印SQL语句 1 Setting配置: 2 默认python 使用的MysqlDB连接,Python3 支持支持pymysql 所有需要在app里面的__init__加上下面配置:
url: re_path('authors/$', views.AuthorView.as_view()), re_path('book/(?P\d+)/$', vie
前提 关于html寻找路线: template 如果在各个APP中存在, Django 会优先找全局template 文件下的html文件,如果全局下的template文件没有相关的html Djan
// GET请求request.GET // POST请求request.POST // 处理文件上传请求request.FILES // 处理如checkbox等多选 接受列表request.get
from bs4 import BeautifulSoup#kindeditordef kindeditor(request): s = ''' <li><s
view.py 配置 html 配置
from django.http import JsonResponse JsonResponse 里面代码会加这一个响应头 kwargs.setdefault('content_type&#
#下面两种是基于QuerySet查询 也就是说SQL中用的jion连表的方式查询books = models.UserInfo.objects.all() print(type(books)) &gt
return HttpResponse("OK") 返回一个字符串 return redirect("/index/") 返回URL return render
from django.http import JsonResponse JsonResponse 里面代码会加这一个响应头 kwargs.setdefault('content_type&#
浏览器有一个很重要的概念——同源策略(Same-Origin Policy)。所谓同源是指,域名,协议,端口相同。不同源的客户端脚本(javascript、ActionScript)在没明确授权的情况
自动发送 > 依赖jQuery文件 实例-->GET请求: 手动发送 > 依赖浏览器XML对象(也叫原生ajax) Ajax主要就是使用 【XmlHttpRequest】对象来完成请
#下面两种是基于QuerySet查询 也就是说SQL中用的jion连表的方式查询books = models.UserInfo.objects.all() print(type(books)) &gt
// GET请求request.GET // POST请求request.POST // 处理文件上传请求request.FILES // 处理如checkbox等多选 接受列表request.get
return HttpResponse("OK") 返回一个字符串 return redirect("/index/") 返回URL return render