失眠网,内容丰富有趣,生活中的好帮手!
失眠网 > 【愚公系列】01月 Django商城项目13-登录界面-QQ登录功能实现

【愚公系列】01月 Django商城项目13-登录界面-QQ登录功能实现

时间:2022-05-16 06:43:12

相关推荐

【愚公系列】01月 Django商城项目13-登录界面-QQ登录功能实现

文章目录

前言1.QQ互联开发者申请2.QQ互联应用申请3.网站对接QQ登录一、django实际对接流程1.创建抽象模型类2.创建QQ用户模型类3.注册应用4.配置QQ登录信息5.登录返回的URL地址和回调信息6.回调页面逻辑功能实现

前言

1.QQ互联开发者申请

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

相关连接:/

第一步:首先使用qq登录

第二步:注册个人应用

注册成功后如下

2.QQ互联应用申请

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

相关连接:/manage.html#/appcreate/web

3.网站对接QQ登录

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

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

一、django实际对接流程

1.创建抽象模型类

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用户模型类

from django.db import modelsfrom utils.models import BaseModelclass OAuthQQUser(BaseModel):"""QQ登录用户数据"""# ForeignKey 我们使用了 其他子应用的模型# 我们采用 '子应用名.模型类名'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.注册应用

# Application references# /en/2.1/ref/settings/#std:setting-INSTALLED_APPSINSTALLED_APPS = ['app',# Add your apps here to enable them'django.contrib.admin','django.contrib.auth','django.contrib.contenttypes','django.contrib.sessions','django.contrib.messages','django.contrib.staticfiles','app.users','app.oauth',]

4.配置QQ登录信息

# QQ登陆相关的QQ_CLIENT_ID = '填写自己的'QQ_CLIENT_SECRET = '填写自己的'QQ_REDIRECT_URI = '填写自己的'

5.登录返回的URL地址和回调信息

from django.shortcuts import renderfrom QQLoginTool.QQtool import OAuthQQfrom DJ_MeiDuo import settingsfrom django import httpfrom django.views import View# Create your views here.class OauthQQURLView(View):def get(self,request):#1.创建实例对象state = 'test'qqoauth = OAuthQQ(client_secret=settings.QQ_CLIENT_SECRET,client_id=settings.QQ_CLIENT_ID,redirect_uri=settings.QQ_REDIRECT_URI,state=state)#2.调用方法login_url = qqoauth.get_qq_url()return http.JsonResponse({'login_url':login_url})class OauthQQUserView(View):def get(self,request):# 1.获取codecode = request.GET.get('code')if code is None:return render(request,'oauth_callback.html',context={'errmsg':'没有获取到指定参数'})# 2. 通过读取文档将code转换为tokenqqoauth = OAuthQQ(client_secret=settings.QQ_CLIENT_SECRET,client_id=settings.QQ_CLIENT_ID,redirect_uri=settings.QQ_REDIRECT_URI)token = qqoauth.get_access_token(code)#3.通过token换取openidopenid = qqoauth.get_open_id(token)# 4. 我们需要根据 openid 进行数据的查询try:qquser = OAuthQQUser.objects.get(openid=openid)except OAuthQQUser.DoesNotExist:# 如果没有同样的openid,则说明用户没有绑定过# 对openid进行一个加密的处理openid_access_token = generate_access_token(openid)return render(request,'oauth_callback.html',context={'openid_access_token':openid_access_token})else:# 如果有同样的openid,则说明用户绑定过# 则直接登陆response = redirect(reverse('contents:index'))#1. 设置登陆状态login(request,qquser.user)#2.设置cookie信息response.set_cookie('username',qquser.user.username,max_age=14*24*3600)return response# return render(request,'oauth_callback.html')def post(self,request):# 1.先接收数据data = request.POST# 2.获取数据mobile = data.get('mobile')password = data.get('pwd')sms_code = data.get('sms_code')access_token = data.get('access_token')# 3.验证数据# 省略# 4.access_token( 加密之后的openid)解密openid = check_access_token(access_token)# 5.根据手机号进行用户信息的判断try:user = User.objects.get(mobile=mobile)except User.DoesNotExist:#如果此手机号之前没有注册过,则重新创建用户user = User.objects.create_user(username=mobile,password=password,mobile=mobile)else:#如果此手机号之前注册过,绑定前要验证密码if not user.check_password(password):return http.HttpResponseBadRequest('密码错误')# 则和用户进行绑定,qquser = OAuthQQUser.objects.create(user=user,openid=openid)# 6.设置登陆的状态login(request,user)# 7.设置cookie信息response = redirect(reverse('contents:index'))response.set_cookie('username',user.username,max_age=14*24*3600)# 8.跳转指定页面return response

加解密方法的封装

from itsdangerous import TimedJSONWebSignatureSerializer as Serializerfrom app.oauth.constants import OPENID_TOKEN_EXPIRE_TIMEfrom DJ_MeiDuo import settingsdef generate_access_token(openid):#1. 创建实例对象s = Serializer(secret_key=settings.SECRET_KEY,expires_in=OPENID_TOKEN_EXPIRE_TIME)#2.组织数据data = {'openid':openid}#3.加密处理token = s.dumps(data)#4. 返回return token.decode()def check_access_token(token):#1.创建实例对象s = Serializer(secret_key=settings.SECRET_KEY, expires_in=OPENID_TOKEN_EXPIRE_TIME)#2. 解密数据result = s.loads(token)# script = {'openid':'xxxx'}#3.返回数据return result['openid']

6.回调页面逻辑功能实现

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="/1999/xhtml" xml:lang="en"><head><meta http-equiv="Content-Type" content="text/html;charset=UTF-8"><title>小徐商城-绑定用户</title><link rel="stylesheet" type="text/css" href="{{ static('css/reset.css') }}" /><link rel="stylesheet" type="text/css" href="{{ static('css/main.css') }}" /><script src="/vue/2.4.2/vue.min.js"></script><script src="/axios/0.18.0/axios.min.js"></script></head><body><div id="app" v-cloak><div><div class="register_con"><div class="l_con fl"><a href="index.html" class="reg_logo"><img src="{{ static('images/logo.png') }}"></a><div class="reg_slogan">商品美 · 种类多 · 欢迎光临</div><div class="reg_banner"></div></div><div class="r_con fr"><div class="reg_title clearfix"><h1>绑定用户</h1></div><div class="reg_form clearfix"><form id="reg_form" method="post" @submit="on_submit">{{csrf_input }}<input type="hidden" name="access_token" value="{{ openid_access_token }}"><ul><li><label>手机号:</label><input type="text" name="mobile" id="phone" @blur="check_mobile" v-model="mobile"><span class="error_tip" v-show="error_mobile">[[error_mobile_message]]</span></li><li><label>密码:</label><input type="password" name="pwd" id="pwd" @blur="check_password" v-model="password"><span class="error_tip" v-show="error_password">请输入8-20位密码</span></li><li><label>图形验证码:</label><input type="text" name="pic_code" id="pic_code" class="msg_input" v-model="image_code"><img :src="image_code_url" @click="generate_image_code" alt="图形验证码" class="pic_code"><span class="error_tip" v-show="error_image_code">请填写图形验证码</span></li><li><label>短信验证码:</label><input type="text" name="sms_code" id="msg_code" class="msg_input" v-model="sms_code" @blur="check_sms_code"><a href="javascript:;" class="get_msg_code" @click="send_sms_code">获取短信验证码</a><span class="error_tip" v-show="error_sms_code">请填写短信验证码</span></li><li class="reg_sub"><input type="submit" value="保 存" name=""></li></ul></form></div></div></div><div class="footer no-mp"><div class="foot_link"><a href="#">关于我们</a><span>|</span><a href="#">联系我们</a><span>|</span><a href="#">招聘人才</a><span>|</span><a href="#">友情链接</a></div><p>CopyRight © 福建小徐网络科技有限公司 All Rights Reserved</p><p>电话:13960699696 闽ICP备*******8号</p></div></div></div><script type="text/javascript" src="{{ static('js/host.js') }}"></script><script type="text/javascript" src="{{ static('js/common.js') }}"></script><script type="text/javascript" src="{{ static('js/oauth_callback.js') }}"></script></body></html>

let vm = new Vue({el: '#app',delimiters: ['[[', ']]'],data: {mobile: '',password: '',image_code: '',sms_code: '',error_mobile: false,error_password: false,error_image_code: false,error_sms_code: false,error_mobile_message: '',error_image_code_message: '',error_sms_code_message: '',error_password_message:'',uuid: '',image_code_url: '',sms_code_tip: '获取短信验证码',sending_flag: false,},mounted(){// 界面获取图形验证码this.generate_image_code();},methods: {// 生成图形验证码的请求地址generate_image_code(){// 生成一个编号 : 严格一点的使用uuid保证编号唯一, 不是很严谨的情况下,也可以使用时间戳this.uuid = generateUUID();// 设置页面中图形验证码img标签的src属性this.image_code_url = "/image_codes/" + this.uuid + "/";},// 检查手机号check_mobile(){let re = /^1[3-9]\d{9}$/;if(re.test(this.mobile)) {this.error_mobile = false;} else {this.error_mobile_message = '您输入的手机号格式不正确';this.error_mobile = true;}},// 检查密码check_password(){let re = /^[0-9A-Za-z]{8,20}$/;if (re.test(this.password)) {this.error_password = false;} else {this.error_password = true;}},// 检查图片验证码check_image_code(){if(!this.image_code) {this.error_image_code_message = '请填写图片验证码';this.error_image_code = true;} else {this.error_image_code = false;}},// 检查短信验证码check_sms_code(){if(!this.sms_code){this.error_sms_code_message = '请填写短信验证码';this.error_sms_code = true;} else {this.error_sms_code = false;}},// 发送手机短信验证码send_sms_code(){if (this.sending_flag == true) {return;}this.sending_flag = true;// 校验参数,保证输入框有数据填写this.check_mobile();this.check_image_code();if (this.error_mobile == true || this.error_image_code == true) {this.sending_flag = false;return;}// 向后端接口发送请求,让后端发送短信验证码let url = '/sms_codes/' + this.mobile + '/?image_code=' + this.image_code+'&image_code_id='+ this.uuid;axios.get(url, {responseType: 'json'}).then(response => {// 表示后端发送短信成功if (response.data.code == '0') {// 倒计时60秒,60秒后允许用户再次点击发送短信验证码的按钮let num = 60;// 设置一个计时器let t = setInterval(() => {if (num == 1) {// 如果计时器到最后, 清除计时器对象clearInterval(t);// 将点击获取验证码的按钮展示的文本回复成原始文本this.sms_code_tip = '获取短信验证码';// 将点击按钮的onclick事件函数恢复回去this.sending_flag = false;} else {num -= 1;// 展示倒计时信息this.sms_code_tip = num + '秒';}}, 1000, 60)} else {if (response.data.code == '4001') {this.error_image_code_message = response.data.errmsg;this.error_image_code = true;} else {// 4002this.error_sms_code_message = response.data.errmsg;this.error_sms_code = true;}this.generate_image_code();this.sending_flag = false;}}).catch(error => {console.log(error.response);this.sending_flag = false;})},// 绑定openidon_submit(){this.check_mobile();this.check_password();this.check_sms_code();if(this.error_mobile == true || this.error_password == true || this.error_sms_code == true) {// 不满足条件:禁用表单window.event.returnValue = false}}}});

如果觉得《【愚公系列】01月 Django商城项目13-登录界面-QQ登录功能实现》对你有帮助,请点赞、收藏,并留下你的观点哦!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。