微博三方登录 Django

  1. 根据新浪微博开放平台获取一下参数

    def get_weibo_():
        app_key = '2223437162'
        app_sercty = 'a08ba58988e2fd427edf74d397462826'
        redirect_uri = 'http://127.0.0.1:8080/weibo_callback'
  2. 拼接微博登录链接

    # 请求地址 https://api.weibo.com/oauth2/authorize
    # 链接需要两个参数支撑   client_id = app_key   redirect_uri = redirect_uri (回调地址)
    https://api.weibo.com/oauth2/authorize?client_id=2223437162&redirect_uri=http://127.0.0.1:8080/weibo_callback
  3. 获取 access_token

    # 微博登录后会回调到回调地址 并且有参数 code
    # 用参数 code 获取 access_token
    # 请求地址 https://api.weibo.com/oauth2/access_token
    def get_weibo_accesstoken(code):
        url = 'https://api.weibo.com/oauth2/access_token'
        # 请求时需要五个参数
        data = {
            'client_id': '2223437162',  # app_key
            'client_secret': 'a08ba58988e2fd427edf74d397462826',  # app_sercty
            'grant_type': 'authorization_code',  # 固定
            'redirect_uri': 'http://127.0.0.1:8080/weibo_callback',  # 回调地址 必须要和平台一致
            'code': code  #  微博登录后的 code 值
        }
        # 发起请求取出返回文本数据
        req = requests.post(url=url, data=data).text
        # 原数据为json类型,将json转为python后为dict(字典)类型,,取出 access_token
        return json.loads(req)['access_token']
  4. 根据 access_token 获取 uid

    # 拿到 access_token 获取 uid
    # 请求地址 https://api.weibo.com/oauth2/get_token_info
    def get_weibo_userinfo(access_token):
        url = 'https://api.weibo.com/oauth2/get_token_info'
        # 只需一个参数 access_token
        data = {'access_token': access_token}
        # 跟获取 access_token 时一样,获取到的数据为json需要转换一下
        req = requests.post(url=url, data=data).text
        # 拿到 uid 返回
        return json.loads(req)['uid']
  5. 总结

    根据参数拼接微博请求链接,将链接放到vue中,当用户点击微博登录跳到微博登录,登录成功后回调给vue,vue从回调中获取code值,将code值交给django,django根据获取到的code值向微博发起请求获access_token,获取到access_token值后在向微博发起请求根据access_token获取用户对应的uid,uid是用户的唯一表示

  6. demo

    # 这个函数没有用就是用来参考得
    # 请求授权 oauth2/authorize   请求用户授权Token
    # 必选   类型及范围  说明
    # client_id    true   string 申请应用时分配的AppKey。
    # redirect_uri true   string 授权回调地址,站外应用需与设置的回调地址一致,站内应用需填写canvas page的地址。
    def get_weibo_():
        app_key = '2223437162'
        app_sercty = 'a08ba58988e2fd427edf74d397462826'
        redirect_uri = 'http://127.0.0.1:8080/weibo_callback'
        url = 'https://api.weibo.com/oauth2/authorize?client_id=%s&redirect_uri=%s' % (app_key, redirect_uri)
    
        # https://api.weibo.com/oauth2/authorize?client_id=2223437162&redirect_uri=http://127.0.0.1:8080/weibo_callback
    
    
    # 获取授权 oauth2/access_token    获取授权过的Access Token
    #      必选 类型及范围  说明
    # client_id    true   string 申请应用时分配的AppKey。
    # client_secret    true   string 申请应用时分配的AppSecret。
    # grant_type   true   string 请求的类型,填写authorization_code
    #
    # grant_type为authorization_code时
    #      必选 类型及范围  说明
    # code true   string 调用authorize获得的code值。
    # redirect_uri true   string 回调地址,需需与注册应用里的回调地址一致。
    def get_weibo_accesstoken(code):
        url = 'https://api.weibo.com/oauth2/access_token'
        data = {
            'client_id': '2223437162',
            'client_secret': 'a08ba58988e2fd427edf74d397462826',
            'grant_type': 'authorization_code',
            'redirect_uri': 'http://127.0.0.1:8080/weibo_callback',
            'code': code
        }
        req = requests.post(url=url, data=data).text
        return json.loads(req)['access_token']
    
    
    # 授权查询 oauth2/get_token_info  查询用户access_token的授权相关信息
    # access_token:用户授权时生成的access_token
    def get_weibo_userinfo(access_token):
        url = 'https://api.weibo.com/oauth2/get_token_info'
        data = {'access_token': access_token}
        req = requests.post(url=url, data=data).text  # 6046178347
        return json.loads(req)['uid']
    
    
    # 微博登录
    class WeiBoCode(APIView):
        def post(self, request):
            code = request.data['code']
            # 拿到code码请求微博获取:access_token
            access_token = get_weibo_accesstoken(code)
            # 拿到 access_token 获取 uid
            uid = get_weibo_userinfo(access_token)
            # 看此 uid 是否在数据库出现过,出现过代表此微博有绑定过邮箱直接返回jwt_token登录成功,反则没有绑定过返回uid让用户绑定
            try:
                s = models.Social.objects.get(plantform=3, uid=uid)
                # 成功不需要绑定已经在平台出现过,生成token并返回
                t = TimedJSONWebSignatureSerializer(settings.SECRET_KEY, 120)
                jwt_token = t.dumps({'userid': s.user.id, 'email': s.user.email}).decode()
                return Response({
                    'status': RET.OK,
                    'data': {
                        'email': s.user.email,
                        'token': jwt_token,
                        'message': error_map[RET.OK]
                    }
                })
            except:
                # 没有绑定 需要先绑定
                return Response({
                    'status': RET.USERERR,
                    'data': {
                        'uid': uid,  # 7339573276
                        'message': error_map[RET.USERERR]
                    }
                })
    
    
    # 微博绑定邮箱
    class WeiBoBind(APIView):
        def post(self, request):
            email = str(request.data.get('email', '')).strip()
            passwd = str(request.data.get('passwd', '')).strip()
            uid = str(request.data.get('uid', '')).strip()
            # 是否为空
            if not all([email, passwd, uid]):
                return Response({
                    'status': RET.NODATA,
                    'data': {
                        'message': error_map[RET.NODATA]
                    }
                })
            # 效验邮箱
            if not re_email(email):
                return Response({
                    'status': RET.DATAERR,
                    'data': {
                        'message': error_map[RET.DATAERR]
                    }
                })
            try:
                # 效验用户名密码
                user = models.User.objects.get(email=email)
                if check_password(passwd, user.passwd):
                    # 用户名和密码都正确,判断此用户是否有第三方微博登录账号,有返回错误
                    if user.social_set.all():
                        return Response({
                            'status': RET.DATAEXIST,
                            'data': {
                                'message': error_map[RET.DATAEXIST]
                            }
                        })
                    models.Social.objects.create(uid=uid, user=user, plantform=3)
                    t = TimedJSONWebSignatureSerializer(settings.SECRET_KEY, 120)
                    jwt_token = t.dumps({'userid': user.id, 'email': user.email}).decode()
                    return Response({
                        'status': RET.OK,
                        'data': {
                            'email': user.email,
                            'token': jwt_token,
                            'message': error_map[RET.OK]
                        }
                    })
            except:
                pass
            return Response({
                'status': RET.ROLEERR,
                'data': {
                    'message': error_map[RET.ROLEERR]
                }
            })

你可能感兴趣的:(微博三方登录 Django)