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

本文详细讲解了如何使用第三方QQ登录并绑定网站账号的过程,包括创建QQ模型类、使用OAuthQQ工具包获取用户授权码、AccessToken及OpenID,以及实现账号绑定的视图逻辑。

上一节已经讲过了如何利用第三方QQ登录。下面讲下 绑定 网站账号的操作。

(1)创建QQ模型类

  • 我们只需要有两个字段
  • user:用来关联 网站账号
  • openid: QQ用户的唯一身份认证信息,相当于身份证。用来调用 openAPI接口,实现业务。
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

具体接口业务流程:

  • 首先我们使用一个 python封装好的, 我们上节讲过,SDK只有 php和 js的,但是我们python就是包多,库多,大牛多呀~ 下面就导入一个 包,用来完成上节讲的 获取用户授权码等等的业务。
  • (1)安装
pip install QQLoginTool
  • (2)使用
    (1)导入
from QQLoginTool.QQtool import OAuthQQ

(2)初始化OAuthQQ对象

  • 这个很好理解,我们上节看文档中的操作,都需要使用到 应用的id,key,和回调地址,所以封装了一个对象,初始化这三个属性
oauth = OAuthQQ(client_id=settings.QQ_CLIENT_ID,
 client_secret=settings.QQ_CLIENT_SECRET,
  redirect_uri=settings.QQ_REDIRECT_URI, state=next
  )

(3)获取QQ登录扫码页面(就是访问此链接可以获取 code,用户授权码),扫码后得到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)

  • 这些就是基本的需要了,很方便。当然内部实现也不复杂,应该是使用了,requests或者 urllib 去发送请求获取这些。

下面就是视图了

  • (1)视图一
    • 我们要做的就是返回 获取 code(用户授权码)的链接
# 获取授权 认证码 code
class OAuthQQURLView(View):
    def get(self, request):
        # 创建授权对象
        oauthqq = OAuthQQ(
            settings.QQ_CLIENT_ID,
            settings.QQ_CLIENT_SECRET,
            settings.QQ_REDIRECT_URI,
            request.GET.get('next')
        )

        # 生成授权地址
        login_url=oauthqq.get_qq_url()

        # 响应
        return http.JsonResponse({
            'code': RETCODE.OK,
            'errmsg':"ok",
            'login_url':login_url
        })

  • (2)视图二
    • (1)get方法
      • 首先这个视图是 请求服务器回调请求我们的
      • 先获取code值
      • 获取 state字段:表示跳转界面
      • 再从code值 ,访问得到 token
      • 通过token获取 oponid
      • 进行判断:
        • 查询数据库,当存在改QQ对象,则跳转页面
        • 若不存在,则是第一次授权,我们挑战到 绑定页面,使该QQ号与 我们网站的账号绑定
class OAuthQQOpenidView(View):
    def get(self, request):
        # 用户授权码
        code = request.GET.get('code')
        # 获取后面的 state跳转界面
        state = request.GET.get('state','/') # 默认值: /

        # 创建授权对象
        oauthqq = OAuthQQ(
            settings.QQ_CLIENT_ID,
            settings.QQ_CLIENT_SECRET,
            settings.QQ_REDIRECT_URI,
            state
        )

        # 根据code获取token
        token = oauthqq.get_access_token(code)

        # 获取openid
        openid = oauthqq.get_open_id(token)

        # 判断是否初次授权
        try:
            qquser = OAuthQQUser.objects.get(openid=openid)
        except:
            # 未查到数据,则为初次授权,显示绑定页面
            # 将openi加密
            json_str = meiduo_signature.dumps({"openid": openid}, constants.OPENID_EXPIRES)            # 显示绑定页面
            context = {
                'token': json_str
            }
            return render(request, 'oauth_callback.html', context)
        else:
            # 查询到授权对象,则状态保持,转到相关页面
            # 得到用户的user对象
            user = qquser.user
            login(request, user)

            response = redirect(state)
            response.set_cookie('username', user.username)
            return response
    • post请求: 用来处理上面提到的第一次 绑定中传来的信息。
      • 接收:openid,mobile,password,sms_code,重定向地址
    # 接受 初次授权数据,进行处理
    def post(self, request):
        # 接收:openid,mobile,password,sms_code
        access_token = request.POST.get('access_token')
        mobile = request.POST.get('mobile')
        pwd = request.POST.get('pwd')
        sms_code = request.POST.get('sms_code')
        # 接受重定向地址
        state = request.GET.get('state', '/')

        # 验证:参考注册的验证
        openid_dict = meiduo_signature.loads(access_token, constants.OPENID_EXPIRES)
        if openid_dict is None:
            return http.HttpResponseForbidden('授权信息无效,请重新授权')
        # 将openid从加密之后的字典中取出来
        openid = openid_dict.get('openid')

        # 处理:初次授权,完成openid与user的绑定
        # 1.判断手机号是否已经使用
        try:
            user = User.objects.get(mobile=mobile)
        except:
            # 2.如果未使用,则新建用户
            user = User.objects.create_user(mobile, password=pwd, mobile=mobile)
        else:
            # 3.如果已经使用,则验证密码
            # 3.1密码正确
            # 3.2密码错误,则提示
            if not user.check_password(pwd):

                return http.HttpResponseForbidden('手机号已经使用,或密码错误')
        # 4.绑定:新建OAuthQQUser对象
        qquser = OAuthQQUser.objects.create(
            user=user,
            openid=openid
        )
        # 状态保持
        login(request, user)
        response = redirect(state)
        response.set_cookie('username', user.username)
        # 响应
        return response

  • 其中涉及到加密和机密的操作,这个等下节再讲一下。主要是为了安全,防止别人恶意伪造数据,访问接口。

另外要说的是:
上面这个逻辑没有涉及到 当一个手机号已经成功绑定了一个qq号,
但是绑定新的qq号时,手机号和密码都正确,
那么也会绑定成功,
也就是说上面代码的这段逻辑,支持多个qq号绑定一个 注册用户,逻辑上面感觉没有问题的。

  • 还有就是我们只是登录业务,其实并没有使用到 后面的 token,openid,我觉得也可以自己构建一个独有的 序列代替openid,但是为了后续业务的扩展,openid当然是最好的,可以调用QQ的业务。
注意:另外不能迷的是,一定要搞清楚,浏览器,QQ服务端,django的关系。 我们在QQ授权登录,扫码或者点击登录之后,此时只是获取到 code(用户授权码)剩下的业务全都是由django做的。 比如扫完码跳转到首页,这些都是django做的。code获取后回调 到django。

步骤:
在这里插入图片描述
点击QQ图标,此链接是 访问Django,获取 可以得到code的链接
在这里插入图片描述
注意这些参数,就是 获取code的 链接了,中途腾讯方面需要进行身份验证,需要QQ登录授权。

下面:扫码之后,直接回到网站首页,这中间的步骤全部是django做的,因为QQ的回调地址是 django端,后续获取code,获取 token,获取openid,以及绑定用户,挑战到首页。都是django做的。

接到这里吧!
over!

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值