read.html5.qq.com,如何通过第三方QQ登录网站首页

news/2024/5/9 7:38:10/文章来源:https://blog.csdn.net/weixin_39658726/article/details/118373571

c4468b3f4df77e96b0a416fa2a870fba.png

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

若想实现QQ登录,需要成为QQ互联的开发者,审核通过才可实现。注册方法参考链接http://wiki.connect.qq.com/%E6%88%90%E4%B8%BA%E5%BC%80%E5%8F%91%E8%80%85

成为QQ互联开发者后,还需创建应用,即获取本项目对应与QQ互联的应用ID,最重要的是拿到APPID,创建应用的方法参考链接http://wiki.connect.qq.com/__trashed-2

申请时的网站域名即项目域名

网站回调域即用户通过扫码后需要跳转到的页面网址

f8251edac78de5e2c61855bb1d258b09.png

QQ登录开发文档连接http://wiki.connect.qq.com/%E5%87%86%E5%A4%87%E5%B7%A5%E4%BD%9C_oauth2-0

此链接中的网站应用概述中 可以看到效果界面展示,然后点击进入网站开发流程,有5个下拉菜单,前两个是前端用的,后面三个是我们后端要用的

90c61634deaf53cba55873574c2b1679.png

按照步骤获取Access_Token和Open_ID

下面是使用QQ登录的流程图

24f959a59a549780afd0588ee5830c6b.png

接下来就是写后台程序了

首先,创建QQ登录模型类,创建一个新的应用oauth,用来实现QQ第三方认证登录。总路由前缀 oauth/

终端进入到/meiduo_mall/apps目录下,使用命令python ../../manage.py startapp oauth 创建子应用oauth,记得创建完之后在settings文件中的INSTALLED_APPS中注册添加此应用,'oauth.apps.OauthConfig'

在meiduo/meiduo_mall/utils/models.py文件中创建模型类基类,用于增加数据新建时间和更新时间。(为什么要在公共的util中增加models呢,因为在模型类基类中创建的create_time,update_time在后面的商品类等中都会用到,方便调用)

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=True, verbose_name="更新时间")

class Meta:

abstract = True # 说明是抽象模型类, 用于继承使用,数据库迁移时不会创建BaseModel的表

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

from django.db import models

from meiduo_mall.utils.models import BaseModel

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)#openid其实就是我们当年申请QQ时,QQ服务器为我们生成的那个唯一标识

class Meta:

db_table = 'tb_oauth_qq'

verbose_name = 'QQ登录用户数据'

verbose_name_plural = verbose_name

接下来,终端进入到包含manage.py文件的meiduo_mall目录下,输入迁移命令

进行数据库迁移

python manage.py makemigrations

python manage.py migrate

第一步:点击QQ登录标签,跳转到QQ登录页面

settings配置文件中添加:

# QQ登录参数QQ_CLIENT_ID = '10147xxxx'

QQ_CLIENT_SECRET = 'c6ce949e04e12ecc909ae6a8b09b637c'

QQ_REDIRECT_URI = 'http://www.xxxx.xxxx:xxxx/oauth_callback.html'

QQ_STATE = '/'

新建oauth/utils.py文件,创建QQ登录辅助工具类

from urllib.parseimport urlencode, parse_qsfrom urllib.requestimport urlopenfrom itsdangerousimport TimedJSONWebSignatureSerializeras Serializer, BadDatafrom django.confimport settingsimport jsonimport loggingfrom .import constants

logger = logging.getLogger('django')classOAuthQQ(object):

""" QQ登录的工具类 """

"""构造方法接收所有的工具方法需要用到的参数"""

def__init__(self, client_id=None, client_secret=None, redirect_uri=None, state=None):

self.client_id = client_idor settings.QQ_CLIENT_ID#appidself.client_secret = client_secretor settings.QQ_CLIENT_SECRET#appkeyself.redirect_uri = redirect_urior settings.QQ_REDIRECT_URI

self.state = stateor settings.QQ_STATE# 用于保存登录成功后的跳转页面路径defget_qq_login_url(self):

"""

获取qq登录的网址

:return: url网址

"""

params = {

'response_type': 'code',#此值固定为code,作用是告诉QQ服务器,此用户拿着QQ在扫码,是为了得到一个code,有code才能得到Access_Token

'client_id': self.client_id,#申请QQ登录成功后,分配给应用的appid'redirect_uri': self.redirect_uri,#网站回调域的网址,必须是注册appid时填写的主域名下的地址,建议设置为网站首页或网站的用户中心。注意需要将url进行URLEncode'state': self.state,#就是next,# QQ登录成功后回去的地方

'scope':'get_user_info',#请求用户授权,手机正在扫码的用户,# 标识扫码最终为了获取QQ用户的信息(openid)}#拼接QQ扫码登录连接login_url='https://graph.qq.com/oauth2.0/authorize?' + urlencode(params)

returnlogin_url

在oauth/views.py中实现视图

# url(r'^qq/authorization/$', views.QQAuthURLView.as_view()),

classQQAuthURLView(APIView):

"""

获取QQ登录的url

"""

defget(self, request):

"""

提供用于qq登录的url

"""

#获取到next参数,实现将来从哪里进入的登录界面,QQ登录成功后,就回到哪里

next = request.query_params.get('next')

oauth = OAuthQQ(state=next)#生成QQ扫码登录连接(逻辑)login_url = oauth.get_qq_login_url()return Response({'login_url': login_url})子应用中的urls中添加路由

from django.conf.urls import url

from . import views

urlpatterns=[

url(r'^qq/authorization/$', views.QQAuthURLView.as_view()),

]

主业务逻辑的urls中添加子应用路由

urlpatterns = [

#QQ登录

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

]

urllib使用说明

在后端接口中,我们需要向QQ服务器发送请求,查询用户的QQ信息,Python提供了标准模块urllib可以帮助我们发送http请求。

urllib.parse.urlencode(query)

c5271f26f63375d4e7f2e2e0eb4f5bf8.png

将query字典转换为url路径中的查询字符串

urllib.parse.parse_qs(qs)

将qs查询字符串格式数据转换为python的字典

urllib.request.urlopen(url, data=None)

发送http请求,如果data为None,发送GET请求,如果data不为None,发送POST请求

返回response响应对象,可以通过read()读取响应体数据,需要注意读取出的响应体数据为bytes类型

第二步:用户扫码登录的回调处理

用户在QQ登录成功后,QQ会将用户重定向回我们配置的回调callback网址,即我们申请QQ登录开发资质时配置的回调地址;

第三步:绑定用户身份接口

业务逻辑:

用户需要填写手机号、密码、图片验证码、短信验证码

如果用户未在美多商城注册过,则会将手机号作为用户名为用户创建一个美多账户,并绑定用户

如果用户已在美多商城注册过,则检验密码后直接绑定用户

注:以下代码合并二三步

新建oauth/serializers.py文件

from rest_framework importserializersfrom .utils importOAuthQQfrom django_redis importget_redis_connectionfrom users.models importUserfrom .models importOAuthQQUserclassQQAuthUserSerializer(serializers.Serializer):"""QQ登录创建用户序列化器"""

#是外界的request.data传过来的注册时的请求体数据

access_token = serializers.CharField(label='操作凭证')

mobile= serializers.RegexField(label='手机号', regex=r'^1[3-9]\d{9}$')

password= serializers.CharField(label='密码', max_length=20, min_length=8)

sms_code= serializers.CharField(label='短信验证码')defvalidate(self, data):#检验access_token

access_token = data['access_token']#获取身份凭证

openid =OAuthQQ.check_save_user_token(access_token)if notopenid:raise serializers.ValidationError('无效的access_token')#将openid放在校验字典中,后面会使用

data['openid'] =openid#检验短信验证码

mobile = data['mobile']

sms_code= data['sms_code']

redis_conn= get_redis_connection('verify_codes')

real_sms_code= redis_conn.get('sms_%s' %mobile)if real_sms_code.decode() !=sms_code:raise serializers.ValidationError('短信验证码错误')#如果用户存在,检查用户密码

try:

user= User.objects.get(mobile=mobile)exceptUser.DoesNotExist:pass

else:

password= data['password']if notuser.check_password(password):raise serializers.ValidationError('密码错误')#将认证后的user放进校验字典中,后续会使用

data['user'] =userreturndatadefcreate(self, validated_data):#获取校验的用户

user = validated_data.get('user')if notuser:#用户不存在,新建用户

user =User.objects.create_user(

username=validated_data['mobile'],

password=validated_data['password'],

mobile=validated_data['mobile'],

)#将用户绑定openid

OAuthQQUser.objects.create(

openid=validated_data['openid'],

user=user

)#返回用户数据

return user

新建oauth/exceptions.py文件

classQQAPIException(Exception):"""自定义QQ异常"""

pass

新建oauth/constants.py文件

#QQ登录保存用户数据的token有效期

SAVE_QQ_USER_TOKEN_EXPIRES=600

使用itsdangerous生成凭据access_token,itsdangerous模块的参考资料连接http://itsdangerous.readthedocs.io/en/latest/

需要安装itsdangerous

pip install itsdangerous

使用TimedJSONWebSignatureSerializer可以生成带有有效期的token在oauth/utils.py文件OAuthQQ辅助类中添加方法:

from urllib.parse import urlencode,parse_qs

from urllib.request import urlopen

from .exceptions import QQAPIException

import json

from itsdangerous import TimedJSONWebSignatureSerializer as Serializer, BadData

from .exceptions import QQAPIException

from . import constants

import logging

# 日志记录器

logger = logging.getLogger('django')

def  get_access_token(self, code):

"""获取access_token"""

# 准备url

url = 'https://graph.qq.com/oauth2.0/token?'

# 准备参数

params = {

'grant_type':'authorization_code',

'client_id':self.client_id,

'client_secret':self.client_secret,

'code':code,

'redirect_uri':self.redirect_uri

}

# 拼接地址

url += urlencode(params)

try:

# 使用code向QQ服务器发送请求获取access_token

response = urlopen(url)

# 获取响应的二进制

response_data = response.read()

# 将response_data转成字符串

# access_token=FE04************************CCE2&expires_in=7776000&refresh_token=88E4************************BE14

response_str = response_data.decode()

# 将response_str转成字典

response_dict = parse_qs(response_str)

# 提取access_token

# response_dict.get('access_token') == [FE04************************CCE2]

access_token = response_dict.get('access_token')[0]

except  Exception as e:

logger.error(e)

raise QQAPIException('获取access_token失败')

return access_token

def  get_openid(self, access_token):

"""

使用access_token向QQ服务器请求openid

:param access_token: 上一步获取的access_token

:return: open_id

"""

# 准备url

url = 'https://graph.qq.com/oauth2.0/me?access_token=' + access_token

# 美多向QQ服务器发送请求获取openid

response_str = ''

try:

response = urlopen(url)

response_str = response.read().decode()

# 返回的数据 callback( {"client_id":"YOUR_APPID","openid":"YOUR_OPENID"} )\n;

response_dict = json.loads(response_str[10:-4])

# 获取openid

openid = response_dict.get('openid')

except Exception as e:

# 如果有异常,QQ服务器返回 "code=xxx&msg=xxx"

data = parse_qs(response_str)

logger.error(e)

raise QQAPIException('code=%s msg=%s' % (data.get('code'), data.get('msg')))

return openid

@staticmethod

def generate_save_user_token(openid):

"""

生成保存用户数据的token

:param openid: 用户的openid

:return: token

"""

serializer = Serializer(settings.SECRET_KEY, expires_in=constants.SAVE_QQ_USER_TOKEN_EXPIRES)

data = {'openid': openid}

token = serializer.dumps(data)

return token.decode()

@staticmethod

def check_save_user_token(token):

"""

检验保存用户数据的token

:param token: token

:return: openid or None

"""

serializer = Serializer(settings.SECRET_KEY, expires_in=constants.SAVE_QQ_USER_TOKEN_EXPIRES)

try:

data = serializer.loads(token)

except BadData:

return None

else:

return data.get('openid')

在oauth/views.py中实现视图:

from rest_framework.response import Response

from rest_framework import status

from rest_framework_jwt.views import api_settings

from rest_framework.generics import GenericAPIView

from .utils import OAuthQQ

from .exceptions import QQAPIException

from .models import OAuthQQUser

from . import serializers

# url(r'^qq/user/$', views.QQAuthUserView.as_view()),?

class QQAuthUserView(GenericAPIView):

"""用户扫码登录的回调处理"""

# 指定序列化器

serializer_class = serializers.QQAuthUserSerializer

def get(self, request):

# 提取code请求参数

code = request.query_params.get('code')

if not code:

return Response({'message':'缺少code'}, status=status.HTTP_400_BAD_REQUEST)

# 创建QQ登录的工具对象

oauth = OAuthQQ()

try:

# 使用code向QQ服务器请求access_token

access_token = oauth.get_access_token(code)

# 使用access_token向QQ服务器请求openid

openid = oauth.get_openid(access_token)

except  QQAPIException:

return Response({'message':'QQ服务异常'}, status=status.HTTP_503_SERVICE_UNAVAILABLE)

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

try:

oauth_user = OAuthQQUser.objects.get(openid=openid)

except OAuthQQUser.DoesNotExist:

# 如果openid没绑定美多商城用户,创建用户并绑定到openid

access_token_openid = OAuthQQ.generate_save_user_token(openid)

return Response({'access_token':access_token_openid})

else:

# 如果openid已绑定美多商城用户,直接生成JWT token,并返回

jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER

jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER

# 获取关联openid的user

user = oauth_user.user

payload = jwt_payload_handler(user)

token = jwt_encode_handler(payload)

# 向前端响应token, user_id,username

return Response({

'token':token,

'user_id':user.id,

'username':user.username

})

def post(self, request):

"""给openid绑定用户数据"""

# 获取序列化器:注册的数据都在POST请求的请求体里面

serializer = self.get_serializer(data=request.data)

# 开启校验

serializer.is_valid(raise_exception=True)

# 保存校验的数据 : create会返回user

user = serializer.save()

# 生成JWT token 响应

jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER

jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER

payload = jwt_payload_handler(user)

token = jwt_encode_handler(payload)

# 向前端响应token, user_id,username

return Response({

'token': token,

'user_id': user.id,

'username': user.username

})

在oauth/urls中 添加路由

urlpatterns=[

# 获取QQ扫码登录连接

url(r'^qq/authorization/$', views.QQAuthURLView.as_view()),

# 获取QQ登录用户信息(code,access_token, openid)

url(r'^qq/user/$', views.QQAuthUserView.as_view()),

]

最后再上一张绑定QQ身份的处理流程图供参考

e3dff8c015cb696271228553aa5c8d24.png

65a094d6f9542ff623929f5cabc75c7f.png

标签:主域名

版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com

特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.luyixian.cn/news_show_781278.aspx

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

网站服务器的10G内存,10G网站空间

10G网站空间 内容精选换一换云速建站各个版本对于流量都不做任何限制,可以无限使用。客户访问和上传下载文档图片都会产生流量,流量为上下行量的总和。云速建站架构包含缓存机制,只有第一次访问的时候,图片下载到本地才会占有流量…

ASP.NET MVC4网站搭建与发布【最新】

ASP.NET MVC4网站搭建与发布 一些往事 2015年,仅仅大二的我怀着一颗创业之心,加入了常熟派英特,成为阳光职场平台的创始之一,并肩负了公司技术部的大梁,当时阳光职场正在从线下服务向互联网化升级过渡。 距我离开自…

使用Github+Hexo搭建个人博客 - Hexo建站(一)

一、博客搭建 1.1.1 安装nodejs 官网: https://nodejs.org/en/ 下载好后, 打开一直下一步即可. 查看是否安装成功 $ node -v v12.10.01.1.2 安装Git Windows: 下载并安装 https://git-scm.com/download/win 1.1.2.1 git设置 配置推送的用户名和邮箱 $ git config --glob…

Github搭建的博客更改为自定义域名 - Hexo建站(二)

本文主要目的: 创建Githubs name.github.io网站后, 想改为自己的域名 更改为自定义域名 1.购买自己想要的域名 2.域名备案 3.域名解析 GitHub Page最新域名解析地址: https://help.github.com/en/github/working-with-github-pages/managing-a-custom-domain-for-your-github…

NexT主题导航图标不显示或者导航链接404 - Hexo建站(三)

图标显示问号 修改主题配置文件: /themes/_config.yml menu:home: /|| homecategories: /categories/|| tharchives: /archives/|| archiveabout: /about/|| user#tags: /tags/ || tags#schedule: /schedule/ || calendar#sitemap: /sitemap.xml || sitemap#commonweal: /404…

添加验证网站之CNAME验证操作-百度搜索资源平台

为了让百度可以搜索到自己的网站内容来提高自己网站的曝光度, 需要下面操作完成. 本文针对通过GitPagesHexo搭建的博客, 来让百度搜索到, 因为前两种方法都是未知原因301, 所以只能使用CNAME验证来完成. 一、查看自己网站是否可以百度搜索到 百度搜索: site:完整域名,若是下图,…

github分支备份博客源文件 - Hexo建站(四)

Hexo建立的博客的所有文件, 刚开始是没有.git文件夹的. 首先进入.deploy_git目录下, 新建一个分支hexo git branch hexo然后将该目录下的.git文件夹复制到博客的根目录下, 也就是上一级目录.在git bash下操作, 切换到hexo分支. git checkout hexo将根目录下的文件先建立索引, …

侧栏中的posts打开的链接错误,修改链接 - Hexo建站(五)

当鼠标移到posts时, 访问的链接是域名/archives/%7C%7C%20archive/, 可见后面的多余了, 问题就是删除后面多余字符 解决多余字符 posts的class"site-state-item site-state-posts" 打开博客根目录/themes/next/layout/_macro/sidebar.swig, 搜索class的值, 快速定…

主页文章添加背景图片后给文章添加阴影效果 - Hexo建站(六)

博客地址预览: http://www.clearlight.com.cn 打开博客主目录文件 -> themes -> next -> source -> css -> _custom -> custom.styl 里面填上如下代码: .post-block {background: rgba(255, 255, 255, 0.84);padding: 25px; }// 主页文章添加阴影效果 .po…

NexT主题网站一直请求static.duoshuo.com,如何取消多说 - Hexo建站(七)

一、问题描述 如上图, 一直在请求, 打开浏览器控制台, 一段时间后, 可以看到响应500. 多说已经关闭, 所以放弃多说, 之前设置多说没成功, 也没管, 因此后面, 一直在请求多说, 很苦恼. 取消主题的配置文件中的duoshuo都设置为false, 还是在一直在请求 😦 二、解决…

GitPage如何对自定义域名开启强制https - Hexo建站(九)

Github搭建的博客更改为自定义域名 - Hexo建站(二) 更改为自己域名后, 正常访问是: http://www.xxx.com 如何开启https进行访问网站? blog仓库的setting选项找到GitHub Pages的项目配置 勾选Enforce HTTPS选项即可开启, 但是如果之前已经开启了自定义域名, 该选项是无法勾选…

NexT主题分页的翻页箭头显示i class=fa fa-angle-right/i - Hexo建站(十)

看了这篇文章, 终于明白, 只能用魔法来战胜魔法 &#x1f603; 解决Hexo博客模板hexo-theme-next的翻页按钮不正常显示问题 显示为: 修改代码的位置: themes\next\layout\_partials\pagination.swig 原来为: {% if page.prev or page.next %}<nav class"pagination&…

hexo如何同时部署到github和coding? - Hexo建站(十一)

部署到github上, 访问的速度实在是太慢了. 所以可以部署到coding上, 两者并不冲突, 而且coding也可以自定义域名. 所以这个操作是很有必要的. 官网: https://coding.net/ 新建账户后, 把公钥加到coding的ssh公钥里面, 添加的时候, 你用你之前添加到github的公钥在添加到coding…

【分享】提取歌曲背景音乐在线网站和GitHub开源项目

提取歌曲背景音乐在线网站和GitHub开源项目前因&#xff1a; 今天一同学找我说希望能把Stewart mac唱的《I Love You》的歌词提取出来做婚礼的背景音乐。在网上没有搜到资源&#xff0c;本来想着用Adobe Audition cs6软件来处理&#xff0c;转念一想&#xff0c;或许可以使用深…

织梦html5上传,dedecms本地调试好的网站怎么上传到服务器

dedecms本地调试好的网站怎么上传到服务器&#xff1f;这个教程只适合菜鸟看哦&#xff01;对于新手来讲绝对有用&#xff0c;这都是我经常用的。1、在本地调试好dede系统后&#xff0c;进入本地网站的后台&#xff1a;点击 系统-----数据库备份/还原默认是&#xff1a;勾选全部…

table 手机 滑动_手机端如何做seo优化?

1前言据国内三大运营商数据来看&#xff0c;中国的手机用户数已达15.7亿&#xff0c;超过3/5的移动用户每个月都会从手机终端访问网页&#xff0c;如今的移动端手机网站比例肯定有提升&#xff0c;但是对于这些存在的移动版本网站来说&#xff0c;小编查看了很大一部分手机网站…

php返回503,网站返回503是什么意思

网站返回503表示服务器资源暂时不可用。当客户端向服务器端发送一个请求的时候&#xff0c;服务器端会给出一个响应&#xff0c;然后返回一个http状态码&#xff0c;如403&#xff0c;表示无权限访问。当客户端向服务端发送一个请求的时候&#xff0c;服务器端会给出一个响应&a…

电脑编程学习_有哪些适合学习电脑编程的网站?

给大家推十三个学习网站&#xff0c;记得收藏学习哦一、慕课网是垂直的互联网IT技能免费学习网站。以独家视频教程、在线编程工具、学习计划、问答社区为核心特色。在这里&#xff0c;你可以找到最好的互联网技术牛人&#xff0c;也可以通过免费的在线公开视频课程学习国内领先…

cdn对动态网站有作用吗_什么是高防CDN?

高防CDN是为了更好的服务网络而出现的&#xff0c;是通过高防DNS来实现的。高防CDN是通过智能化的系统判断来路&#xff0c;再反馈给用户&#xff0c;可以减轻用户使用过程的复杂程度。通过智能DNS解析&#xff0c;能让网站访问者连接到响应的服务器上&#xff0c;以避免某个服…

网站优化之友情链接的选择标准、友情链接的管理及如何找取

相信看完之前的文章后&#xff0c;你已能够独立布局一个最适合seo的页面&#xff0c;关键字、标题的写法请参看我的文章&#xff1a;[seo系列专题&#xff1a;如何有效选择关键字及关键字 title写法] 。好的架构加上原创的内容将是你成功的基石&#xff0c;一味的采集会使SE认为…