web网站--第三方登录功能

下面,我将以QQ第三方登录为例进行讲解,其它类型的第三方登录都是类似的流程。

1、QQ互联开发平台申请成为开发者
若想实现QQ登录,需要成为QQ互联的开发者,审核通过了才可以实现。

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

3、根据文档进行开发

3.1、准备工作
QQ登录参数
我们申请的客户端id
QQ_CLIENT_ID
我们申请的客户端秘钥
QQ_CLIENT_SECRET
我们申请时添加的:登录成功后的回调路径
QQ_REDIRECT_URI

3.2、放置 QQ登录的图标(目的:让我们点击QQ图标实现第三方第三方登录)

3.3、根据oauth2.0 来获取code和token
对于应用而言,需要进行两步:

  1. 获取Authorization Code;
  2. 通过Authorization Code获取Access Token

3.4、通过token换取openid
openid是此网站上唯一对应用户身份的标识,网站可将此ID进行存储便于用户下次登录时辨识其身份,或将其与用户在网站上的原有账号进行绑定。

最终需要保存openid,所以需要去定义一个模型来保存。

定义QQ登录模型类
创建一个新的应用oauth,用来实现QQ第三方认证登录
在这里插入图片描述
在oauth/models.py中定义QQ身份(openid)和用户模型类User的关联关系

from django.db import models
from elephantmall.utils.models import BaseModel

# Create your models here.

class OAuthQQUser(BaseModel):
    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

QQ登录工具QQloginTool
1、QQLoginTool介绍
该工具封装了对接QQ互联的请求操作
可用于快速实现QQ登录的一种工具包

2、QQLoginTool安装

pip3 install QQLoginTool

3、QQLoginTool使用说明

  1. 导入
    from QQLoginTool.QQtool import OAuthQQ
    
  2. 初始化OAuthQQ对象
    qq = OAuthQQ(client_id=dev.QQ_CLIENT_ID,client_secret=dev.QQ_CLIENT_SECRET,redirect_uri=dev.QQ_REDIRECT_URI,state='xxxx')
    
  3. 获取QQ登录扫码页面,扫码后得到Authorization Code
    qq_login_url = qq.get_qq_url()
    
  4. 通过Authorization Code 获取 Access Token
    token = qq.get_access_token(code)
    
  5. 通过Access Token 获取 OpenID
    openid = qq.get_open_id(token)
    

当点击QQ登录的图标,触发url链接跳转
在这里插入图片描述
在这里插入图片描述
在视图中生成第三方登录的链接地址并返回
在这里插入图片描述
当扫码并确认登录之后,会已GET的形式跳转到settings.py配置文件中的QQ_REDIRECT_URI并携带code和state两个参数信息

接下来,url会触发另外一个视图类,通过code获取token,通过token获取openid
在这里插入图片描述
接下来是openid是否绑定用户的处理逻辑
在这里插入图片描述
在这里插入图片描述
如上代码所示,通过查询QQ登录模型表,如果有记录,执行else分支,实现状态保持、重定向、设置cookie

如果没有记录,加密OpenID,携带加密后的信息,跳转到绑定页面oauth_callback.html

在这里插入图片描述
绑定用户的最终需求:绑定商城账号和QQ的OpenID
点击"保存"按钮,前端需要提交:手机号、密码、手机验证码、OpenID

后端业务逻辑:
接收请求
获取请求参数 openid
根据手机号进行用户信息的查询
查询到手机号已经注册。判断密码是否正确。就可以直接绑定用户和openid信息
查询到手机号没有注册。我们就创建一个user信息,然后在绑定
完成状态保持
返回响应

# 提取数据
mobile = request.POST.get("mobile")
password = request.POST.get("password")
sms_code = request.POST.get("sms_code")
access_token = request.POST.get("access_token")
state = request.GET.get("state")

# 校验数据
# 检查参数是否齐全
if not all([mobile, password, sms_code, access_token]):
	return HttpResponseForbidden("缺少必须的数据")

# 判断手机号格式是否正确
if not re.match(r"^1[345789]\d{9}$", mobile):
	return HttpResponseForbidden("手机号码格式错误")

# 判断密码格式是否正确
if not re.match(r"^[0-9A-Za-z]{8,20}$", password):
	return HttpResponseForbidden("密码格式错误")

# 判断短信验证码是否一致
conn = get_redis_connection("sms_code")
sms_code_server = conn.get(mobile)
if sms_code_server is None:
	return render(request, 'oauth_callback.html', {'sms_code_errmsg': '短信验证码已失效'})
if sms_code != sms_code_server.decode():
	return render(request, 'oauth_callback.html', {'sms_code_errmsg': '短信验证码错误'})

# 判断openid是否有效
open_id = Signer.unsign(access_token)
if open_id is None:
	return render(request, 'oauth_callback.html', {'openid_errmsg': '无效的openid'})
else:
	open_id = open_id["open_id"]

# 处理逻辑
try:
	# 查询手机号用户是否存在
	user = User.objects.get(mobile=mobile)
except User.DoesNotExist:
	# 用户不存在, 创建用户
	user = User.objects.create_user(username=mobile, mobile=mobile, password=password)
else:
	# 用户存在,检查用户密码是否正确
	if not user.check_password(password):
		return render(request, 'oauth_callback.html', {'account_errmsg': '用户名或密码错误'})
# 绑定用户
try:
	OAuthQQUser.objects.create(user=user, openid=open_id)
except DatabaseError:
	return render(request, 'oauth_callback.html', {'qq_login_errmsg': 'QQ登录失败'})

# 登陆状态保持
login(request, user)
response = redirect(state)
# 登陆时把用户名写入 cookie
response.set_cookie("username", user.username, expires=constants.USERNAME_COOKIE_EXPIRES)

# 响应
return response

openid 我们传递给了前端。这个敏感数据,我们最好加密处理一下。

自定义Signer类,封装itsdangerous工具的加密和解密方法

from django.conf import settings
from itsdangerous import BadSignature, TimedJSONWebSignatureSerializer

from woniu_mall.utils import constants


class Signer(object):
    serializer = TimedJSONWebSignatureSerializer(settings.SECRET_KEY, expires_in=constants.OPENID_SIGN_EXPIRES)

    @classmethod
    def sign(cls, obj):
        """
        对python字典先进行json序列化,再对序列化结果进行签名
        :param obj:
        :return: 签名后的字符串
        """
        token = cls.serializer.dumps(obj)
        return token.decode()

    @classmethod
    def unsign(cls, s):
        """
        对传入的字符串验证签名, 验证成功返回字符串中的被签名的数据对应的python字典
        :param s: 要验证的签名字符串
        :return: python字典
        """
        try:
            obj = cls.serializer.loads(s)
        except BadSignature:
            obj = None
        return obj

总的概括:
QQ第三方登录流程

1、QQ互联开发平台申请成为开发者
2、创建应用,获取QQ_CLIENT_ID、QQ_CLIENT_SECRET、QQ_REDIRECT_URI三个QQ登录的参数
3、前端放置QQ登录的图标
4、后端定义QQ登录模型类
5、当点击QQ登录的图标之后,触发链接,跳转到后端逻辑,后端实现生成第三方登录的链接地址并返回
6、用户在弹出的页面中扫码,确认登记之后,会生成一个携带code的链接,该链接会触发后端的逻辑,后端根据该code获取token,再根据token获取openid,在查询openid看有没有记录,如果没有,携带解密后的openid跳转到绑定手机号的页面,如果有,保持登录状态设置cookie,跳转到指定页面
7、在绑定页面,填写信息校验之后,点击保存或确认,会将openid、手机号、密码、手机验证码信息发送给后端,后端根据手机号和密码,查询数据库,没有则插入新数据,有则校验手机号和密码是否配对。然后在QQ登录模型类中创建记录。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值