二、QQ登录

2.1 QQ登录开发文档

QQ登录:即我们所说的第三方登录,是指用户可以不在本项目中输入密码,而直接通过第三方的验证,成功登录本项目。

1. QQ互联开发者申请步骤

若想实现QQ登录,需要成为QQ互联的开发者,审核通过才可实现。

  • 相关连接:http://wiki.connect.qq.com/%E6%88%90%E4%B8%BA%E5%BC%80%E5%8F%91%E8%80%85

2. QQ互联应用申请步骤

成为QQ互联开发者后,还需创建应用,即获取本项目对应与QQ互联的应用ID。

  • 相关连接:http://wiki.connect.qq.com/__trashed-2

3. 网站对接QQ登录步骤

QQ互联提供有开发文档,帮助开发者实现QQ登录。

  • 相关连接:http://wiki.connect.qq.com/%E5%87%86%E5%A4%87%E5%B7%A5%E4%BD%9C_oauth2-0

4. QQ登录流程分析

5. 知识要点

  1. 当我们在对接第三方平台的接口时,一定要认真阅读第三方平台提供的文档。文档中一定会有接口的使用说明,方便我们开发。

2.2 定义QQ登录模型类

QQ登录成功后,我们需要将QQ用户和美多商场用户关联到一起,方便下次QQ登录时使用,所以我们选择使用MySQL数据库进行存储。

1. 定义模型类基类

为了给项目中模型类补充数据创建时间更新时间两个字段,我们需要定义模型类基类。 在meiduo_mall.utils/models.py文件中创建模型类基类。

from django.db import modelsclass BaseModel(models.Model):"""为模型类补充字段"""create_time = models.DateTimeField(auto_now_add=True, verbose_name="创建时间")update_time = models.DateTimeField(auto_now=True, verbose_name="更新时间")class Meta:abstract = True  # 说明是抽象模型类, 用于继承使用,数据库迁移时不会创建BaseModel的表

2. 定义QQ登录模型类

创建一个新的应用oauth,用来实现QQ第三方认证登录。【一个新的子应用】

# oauth
url(r'^oauth/', include('oauth.urls')),

oauth/models.py中定义QQ身份(openid)与用户模型类User的关联关系

from django.db import models
from meiduo_mall.utils.models import BaseModel# Create your models here.
class OAuthQQUser(BaseModel):"""QQ登录用户数据"""user = models.ForeignKey('users.User', on_delete=models.CASCADE, verbose_name='用户')openid = models.CharField(max_length=64, verbose_name='openid', db_index=True)class Meta:db_table = 'tb_oauth_qq'verbose_name = 'QQ登录用户数据'verbose_name_plural = verbose_name

3. 迁移QQ登录模型类

$ python manage.py makemigrations
$ python manage.py migrate

2.3 QQ登录工具QQLoginTool

1. QQLoginTool介绍

  • 该工具封装了QQ登录时对接QQ互联接口的请求操作。可用于快速实现QQ登录。

2. QQLoginTool安装

pip install QQLoginTool

3. QQLoginTool使用说明

1.导入

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)

3.获取QQ登录扫码页面,扫码后得到Authorization Code

login_url = oauth.get_qq_url()

4.通过Authorization Code获取Access Token

access_token = oauth.get_access_token(code)

5.通过Access Token获取OpenID

openid = oauth.get_open_id(access_token)

2.4 OAuth2.0认证获取openid

待处理业务逻辑

# 提取code请求参数
# 使用code向QQ服务器请求access_token
# 使用access_token向QQ服务器请求openid
# 使用openid查询该QQ用户是否在美多商城中绑定过用户
# 如果openid已绑定美多商城用户,直接生成JWT token,并返回
# 如果openid没绑定美多商城用户,创建用户并绑定到openid

1. 获取QQ登录扫码页面

1.请求方式

选项 方案
请求方法 GET
请求地址 /qq/login/

总路由:

子路由:

from django.conf.urls import url
from . import viewsurlpatterns = [#  提供QQ登录扫码页面url(r'^qq/login/$', views.QQAuthURLView.as_view()),]

2.请求参数:查询参数

参数名 类型 是否必传 说明
next string 用于记录QQ登录成功后进入的网址

3.响应结果:JSON

字段 说明
code 状态码
errmsg 错误信息
login_url QQ登录扫码页面链接

4.后端逻辑实现

from django.shortcuts import render
from django.views import View
from QQLoginTool.QQtool import OAuthQQ
from django import http
from django.conf import settings
from meiduo_mall.utils.response_code import RETCODE# Create your views here.class QQAuthURLView(View):"""提供QQ登录页面网址--https://graph.qq.com/oauth2.0/authorize?response_type=code&client_id=xxx&redirect_uri=xxx&state=xxx"""def get(self, request):#  next表示从哪个方面进入到的登录页面,将来登录成功后,就自动回到那个页面next = request.GET.get('next')#  获取QQ登录网址oauth = OAuthQQ(client_id=settings.QQ_CLIENT_ID, client_secret=settings.QQ_CLIENT_SECRET, redirect_uri=settings.QQ_REDIRECT_URI, state=next)login_url = oauth.get_qq_url()return http.JsonResponse({'code': RETCODE.OK, 'errmsg': 'OK', 'login_url': login_url})

5.QQ登录参数

QQ_CLIENT_ID = '101518219'
QQ_CLIENT_SECRET = '418d84ebdc7241efb79536886ae95224'
QQ_REDIRECT_URI = 'http://www.meiduo.site:8000/oauth_callback'

2. 接收Authorization Code

提示:

  • 用户在QQ登录成功后,QQ会将用户重定向到我们配置的回调网址。
  • 在QQ重定向到回调网址时,会传给我们一个Authorization Code
  • 我们需要拿到Authorization Code完成OAuth2.0认证获取openid
  • 在本项目中,我们申请QQ登录开发资质时配置的回调网址为:
    • http://www.meiduo.site:8000/oauth_callback
  • QQ互联重定向的完整网址为:
    • http://www.meiduo.site:8000/oauth_callback/?code=AE263F12675FA79185B54870D79730A7&state=%2F    【%2f是指的根路径】
class QQAuthUserView(View):"""用户扫码登录的回调处理"""def get(self, request):"""Oauth2.0认证"""# 接收Authorization Codecode = request.GET.get('code')if not code:return http.HttpResponseForbidden('缺少code')pass
url(r'^oauth_callback/$', views.QQAuthUserView.as_view()),

3. OAuth2.0认证获取openid

  1. 使用code向QQ服务器请求access_token
  2. 使用access_token向QQ服务器请求openid
class QQAuthUserView(View):"""用户扫码登录的回调处理"""def get(self, request):"""Oauth2.0认证"""# 提取code请求参数code = request.GET.get('code')if not code:return http.HttpResponseForbidden('缺少code')# 创建工具对象oauth = OAuthQQ(client_id=settings.QQ_CLIENT_ID, client_secret=settings.QQ_CLIENT_SECRET, redirect_uri=settings.QQ_REDIRECT_URI)try:# 使用code向QQ服务器请求access_tokenaccess_token = oauth.get_access_token(code)# 使用access_token向QQ服务器请求openidopenid = oauth.get_open_id(access_token)except Exception as e:logger.error(e)return http.HttpResponseServerError('OAuth2.0认证失败')pass

4. 本机绑定www.meiduo.site域名

1.ubuntu系统或者Mac系统

编辑 /etc/hosts

2.Windows系统

编辑 C:\Windows\System32\drivers\etc\hosts

2.5 openid是否绑定用户的处理

1. 判断openid是否绑定过用户

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

from .models import OAuthQQUser......
try:oauth_user = OAuthQQUser.objects.get(openid=openid)
except OAuthQQUser.DoesNotExist:# 如果openid没绑定美多商城用户pass
else:# 如果openid已绑定美多商城用户pass

2. openid已绑定用户的处理

如果openid已绑定美多商城用户,直接生成状态保持信息,登录成功,并重定向到首页。

from django.contrib.auth import login
from django.shortcuts import redirect
from django.urls import reverse......
try:oauth_user = OAuthQQUser.objects.get(openid=openid)
except OAuthQQUser.DoesNotExist:# 如果openid没绑定美多商城用户pass
else:# 如果openid已绑定美多商城用户# 实现状态保持qq_user = oauth_user.userlogin(request, qq_user)# 响应结果next = request.GET.get('state')response = redirect(next)# 登录时用户名写入到cookie,有效期15天response.set_cookie('username', qq_user.username, max_age=3600 * 24 * 15)return response

3. openid未绑定用户的处理

  • 为了能够在后续的绑定用户操作中前端可以使用openid,在这里将openid签名后响应给前端。
  • openid属于用户的隐私信息,所以需要将openid签名处理,避免暴露。
try:oauth_user = OAuthQQUser.objects.get(openid=openid)
except OAuthQQUser.DoesNotExist:# 如果openid没绑定美多商城用户access_token = generate_eccess_token(openid)context = {'access_token': access_token}return render(request, 'oauth_callback.html', context)
else:# 如果openid已绑定美多商城用户# 实现状态保持qq_user = oauth_user.userlogin(request, qq_user)# 重定向到主页response = redirect(reverse('contents:index'))# 登录时用户名写入到cookie,有效期15天response.set_cookie('username', qq_user.username, max_age=3600 * 24 * 15)return response

oauth_callback.html中渲染access_token

<input v-model="access_token" type="hidden" name="access_token" value="{{ access_token }}">

4. 补充itsdangerous的使用    【此处的加密是可逆的,密码的加密是不可逆的】

  • itsdangerous模块的参考资料链接 http://itsdangerous.readthedocs.io/en/latest/

  • 安装:pip install itsdangerous

  • TimedJSONWebSignatureSerializer的使用

    • 使用TimedJSONWebSignatureSerializer可以生成带有有效期token

示例代码:

from itsdangerous import TimedJSONWebSignatureSerializer as Serializer
from django.conf import settings# serializer = Serializer(秘钥, 有效期秒)
serializer = Serializer(settings.SECRET_KEY, 300)
# serializer.dumps(数据), 返回bytes类型
token = serializer.dumps({'mobile': '18512345678'})
token = token.decode()# 检验token
# 验证失败,会抛出itsdangerous.BadData异常
serializer = Serializer(settings.SECRET_KEY, 300)
try:data = serializer.loads(token)
except BadData:return None

补充:openid签名处理 

  • oauth.utils.py  新建utils.py
from itsdangerous import TimedJSONWebSignatureSerializer as Serializer
from django.conf import settings
from . import constants_oauth
from itsdangerous import BadDatadef generate_access_token(openid):"""签名openid:param openid: 用户的openid:return: access_token"""#  创建序列化器对象serializer = Serializer(settings.SECRET_KEY, expires_in=constants_oauth.ACCESS_TOKEN_EXPIRES)#  准备待序列化的字典data = {'openid': openid}#  调用dumps方法进行序列化token = serializer.dumps(data)return token.decode()

新建工具文件constants_oauth.py:

# access_token有效期,单位秒
ACCESS_TOKEN_EXPIRES = 600

2.6 openid绑定用户实现

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

  • 当用户输入的手机号对应的用户已存在

    • 直接将该已存在用户跟openid绑定
  • 当用户输入的手机号对应的用户不存在
    • 新建一个用户,并跟openid绑定
from .utils import generate_access_token
import re
from django_redis import get_redis_connection
from meiduo_mall.apps.users.models import User
from .utils import check_access_tokenclass QQAuthUserView(View):"""用户扫码登录的回调处理"""def get(self, request):"""Oauth2.0认证"""......def post(self, request):"""美多商城用户绑定到openid"""# 接收参数mobile = request.POST.get('mobile')pwd = request.POST.get('password')sms_code_client = request.POST.get('sms_code')access_token = request.POST.get('access_token')# 校验参数# 判断参数是否齐全if not all([mobile, pwd, sms_code_client]):return http.HttpResponseForbidden('缺少必传参数')# 判断手机号是否合法if not re.match(r'^1[3-9]\d{9}$', mobile):return http.HttpResponseForbidden('请输入正确的手机号码')# 判断密码是否合格if not re.match(r'^[0-9A-Za-z]{8,20}$', pwd):return http.HttpResponseForbidden('请输入8-20位的密码')# 判断短信验证码是否一致redis_conn = get_redis_connection('verify_code')sms_code_server = redis_conn.get('sms_%s' % mobile)if sms_code_server is None:return render(request, 'oauth_callback.html', {'sms_code_errmsg':'无效的短信验证码'})if sms_code_client != sms_code_server.decode():return render(request, 'oauth_callback.html', {'sms_code_errmsg': '输入短信验证码有误'})# 判断openid是否有效:错误提示放在sms_code_errmsg位置openid = check_access_token(access_token)if not openid:return render(request, 'oauth_callback.html', {'openid_errmsg': '无效的openid'})# 保存注册数据try:user = User.objects.get(mobile=mobile)except User.DoesNotExist:# 用户不存在,新建用户user = User.objects.create_user(username=mobile, password=pwd, mobile=mobile)else:# 如果用户存在,检查用户密码if not user.check_password(pwd):return render(request, 'oauth_callback.html', {'account_errmsg': '用户名或密码错误'})# 将用户绑定openidtry:OAuthQQUser.objects.create(openid=openid, user=user)except DatabaseError:return render(request, 'oauth_callback.html', {'qq_login_errmsg': 'QQ登录失败'})# 实现状态保持login(request, user)# 响应绑定结果next = request.GET.get('state')response = redirect(next)# 登录时用户名写入到cookie,有效期15天response.set_cookie('username', user.username, max_age=3600 * 24 * 15)return response

utils.py

def check_access_token(access_token_openid):"""反解、反序列化access_token_openid"""#  创建序列化对象serializer = Serializer(settings.SECRET_KEY, expires_in=constants_oauth.ACCESS_TOKEN_EXPIRES)#  反序列化openid密文try:data = serializer.loads(access_token_openid)except BadData:  # openid过期return Noneelse:#  返回openid明文return data.get('openid')

美多商城之用户登录(QQ登录)相关推荐

  1. Springboot网站第三方登录——QQ登录

    Springboot网站第三方登录--QQ登录 这段时间为了做这几个第三方登录,走了很多弯路,跳了很多坑,为以后使用特地记录下来. 由于做了多个登录,所以代码做了一定程度的封装,大致如下: //多个登 ...

  2. 第三方平台授权登录— —QQ登录

    第三方平台授权登录- -QQ登录 本来前两天开开心心!心情乐乐!居然因为自己没有仔细看代码.居然被埋在这里两天!呜呜!怒火中烧!不行,我要去消灭 五碗大米饭 来平复我的心情! <程序运行图> ...

  3. 美多商城之用户登录(账号登录)

    一.账号登录 1.1用户名登录 1. 用户名登录逻辑分析 2. 用户名登录接口设计   [仍在user子项目中] 1.请求方式 选项 方案 请求方法 POST 请求地址 /login/ urls.py ...

  4. 完整电商项目--(四)用户登录(4):第三方登录-QQ登录(续,关联网站账号)

    文章目录 上一节已经讲过了如何利用第三方QQ登录.下面讲下 绑定 网站账号的操作. (1)创建QQ模型类 具体接口业务流程: 下面就是视图了 注意:另外不能迷的是,一定要搞清楚,浏览器,QQ服务端,d ...

  5. Django项目实战 ----用户使用QQ登录

    QQ登录流程 点击前端QQ登录的请求按钮,弹出扫码页面,用于手机扫码授权 如果之前登录过,那么就直接登录成功 如果是第一次使用QQ登录,会提示绑定之前的账号或者输入手机号 QQ登录流程准备的配置工作 ...

  6. 美多商城之用户中心(添加和验证邮箱)

    二.添加和验证邮箱 2.1 添加邮箱后端逻辑 1. 添加邮箱接口设计和定义 1.请求方式 选项 方案 请求方法 PUT 请求地址 /emails/ # 添加邮箱url(r'^emails/$', vi ...

  7. Python_美多商城(用户中心)_5

    用户基本信息 用户基本信息逻辑分析 1. 用户基本信息逻辑分析 以下是要实现的后端逻辑 用户模型补充email_active字段 查询并渲染用户基本信息 添加邮箱 发送邮箱验证邮件 验证邮箱 提示: ...

  8. 【Spring Security OAuth2笔记系列】- Spring Social第三方登录 - QQ登录下

    qq登录下 前面把所有的代码组件都弄好了.现在可以开启调试了 在这之前你需要有一个qq互联的应用:也就是为了拿到appid和appSecret:自己去qq互联创建一个应用即可 这里讲下本地怎么调试应用 ...

  9. Android 三方登录 - QQ登录

    由于项目需要三方登录,所以根据官方文档和一些其他资料,完成了一个Demo,这里记录一下. (1)申请腾讯开发者账号 到腾讯开发这平台(http://open.qq.com/)注册账号,很简单的. (2 ...

最新文章

  1. mongoose简单使用
  2. React中如何优雅的捕捉事件错误
  3. 开启Nginx的目录文件列表功能
  4. Ansible系列(六):循环和条件判断
  5. 软件测试工程师笔试试题
  6. c语言malloc面试题,c语言面试最必考的十道试题,求职必看!!!
  7. pthread_join/pthread_exit用法实例
  8. 前端学习(1931)vue之电商管理系统电商系统之美化一层循环的UI结构删除业务逻辑实现分配权限的对话框实现
  9. POJ 1860 Currency Exchange (SPFA松弛)
  10. 数聚新动能 数创大未来——2016中国国际大数据大会
  11. DriverMessageBean配置详解
  12. 在组织中管理 Windows Hello 企业版
  13. java疯狂讲义笔记整理(第二版第一部分)
  14. JWT的Java使用 (JJWT)
  15. ADS EM MODEL 问题
  16. 堆排序算法过程图解_堆排序算法
  17. c++语言里平方根值函数,函数式编程之函数定义与使用(以scala语言为例)
  18. solve函数c语言_c语言:回溯解数独程序
  19. 阿里云6·18新玩法上线:邀好友送天猫超市卡 更有机会赢得iPhone 12 Pro!
  20. Generating Summaries with Topic Templates and Structured Convolutional Decoders笔记

热门文章

  1. AV1时代要来了,超高清视频时代视频编码技术的机遇与挑战
  2. 必看,10篇定义计算机视觉未来的论文
  3. 自动驾驶人的福音!Lyft公开Level 5部署平台Flexo细节
  4. @程序员,Python 3还有哪些未Get的潜藏技能?| 技术头条
  5. 一键fxxk,代码修复神器拯救你
  6. 马斯克晒特斯拉Autopilot疯狂驾驶模式,称还要开发“极速惊魂”模式
  7. 资源 | 深度学习图像标注工具汇总
  8. 资源 | 4天学会PyTorch!香港科技大学开放PyTorch机器学习课件资源
  9. UUID正在被NanoID取代?
  10. 好家伙!JDK16 GA 终于发布,内置 Lombok 的功能,真的顶?