一、第三方登录流程图
二、Flask代码实现
1.配置三方登录 判断绑定就直接登录
代码如下(示例):
# 微博三方登录
class Weibo_login(Resource):
def get_weibo_user(self, code):
# 构造参数获取weibo的用户信息
# base_url 微博三方登录文档里登录请求的地址
base_url = 'https://api.weibo.com/oauth2/access_token'
data_ = {
"client_id": "2775107052", # 申请应用时分配的AppKey
"client_secret": "718b38b04fc387700cc1595b30875b19", # 申请应用时分配的AppSecret
"grant_type": "authorization_code", # 请求的类型,填写authorization_code
"redirect_uri": "http://127.0.0.1:8080/weibo", # 回调地址,需与注册应用里的回调地址一致
"code": code, # 用户成功登录三方后返回给后端的用户信息标识
}
try:
# 发送获取用户信息的请求 传入地址 和 数据
resp = requests.post(url=base_url, data=data_).json()
print("resp=========>", resp)
except Exception as e:
print(f'获取微博用户数据失败{e}')
return {'code': 500, "message": 'post 获取微博用户信息失败'}
if not resp['access_token']:
return {'code': 400, "message": '根据code获取微博用户信息失败'}
user_info = resp
# 返回用户信息
return user_info
def get(self):
"""根据code 获取微博用户信息"""
parser = reqparse.RequestParser()
parser.add_argument('code')
args = parser.parse_args()
# 1.获取code值
# 用户成功登录三方后返回给后端的用户信息标识
code = args.get('code')
print('code:返回给后端的用户信息标识', code)
# get_weibo_user 上边定义的方法 :构造参数获取weibo的用户信息
user_info = self.get_weibo_user(code)
print('user_info:获取的weibo的用户信息', user_info)
access_token = user_info['access_token']
# 在三方登录的关系表内查询该用户是否已绑定
weibo_user = OAuthUserModel.query.filter_by(oauth_id=access_token, oauth_type='weibo').first()
if not weibo_user: # 未绑定 响应去绑定
return {'massage': '未绑定, 请前往绑定', 'uid': access_token, 'code': 400}
else: # 绑定 查询用户数据 生成token 返回响应
user = Users.query.filter_by(uid=weibo_user.user).first()
payload = {
'user_id': user.uid,
'user_name': user.account,
}
# generate_token 封装的 生成token的方法
token = generate_token(payload)
if token:
return {'code': 200, "account": user.account, 'uid': user.uid, 'token': token}
2.未绑定 绑定方法
# 绑定微博
class WeiboBindUser(Resource):
def post(self):
# 接收数据 判断用户是否存在 存在 校验密码 通过校验加入三方表 生成token 不存在 响应注册
parser = reqparse.RequestParser()
argss = ['account', 'password', 'unid']
for i in argss:
parser.add_argument(i)
args = parser.parse_args()
account = args['account']
password = args['password']
unid = args['unid'] # access_token
user = Users.query.filter_by(account=account).first()
if not user:
return {'message': '请先注册', 'code': 400}
pwd_bool = check_password_hash(user.password, password)
if not pwd_bool:
return {'message': '密码错误', 'code': 400}
# 加入三方表
user_weibo = OAuthUserModel(oauth_id=unid, user=user.uid, oauth_type='weibo')
db.session.add(user_weibo)
db.session.commit()
# 生成token
payload = {
'user_id': user.uid,
'user_name': account,
}
token = generate_token(payload)
return {'code': 200, 'account': account, 'token': token, 'uid': user.uid}
3.导包
import base64
import hmac
import json
import time
import urllib
from urllib.parse import parse_qs
import requests
from flask import Blueprint, current_app
from flask_restful import Api, Resource, reqparse
from werkzeug.security import check_password_hash
from common.jwt.token_generate import generate_token
from common.models import db
from common.models.users import OAuthUserModel, Users
from common.utils.output_json import my_output_json #自定义的返回格式 封装的方法