1.账号密码登录获取token
app/models/user.py
from . import db
from .base import Base
from werkzeug.security import generate_password_hash, check_password_hash
from app.libs.error_code import My_notfound, AuthFail
class User(Base):
......
......
@staticmethod # 登录验证用户是否存在,密码是否一致
def vertify_user_password(account, password):
user = User.query.filter_by(email=account).first()
if not user:
raise My_notfound()
if not user.check_pwd(password):
raise AuthFail()
return {"user": user}
app/v1/token.py
from app.libs.red_print import Red_Print
from flask import request, current_app, jsonify
from app.validators.forms import ClientForm
from app.libs.enums import ClientTypeEnum
from app.models.user import User
from itsdangerous import TimedJSONWebSignatureSerializer as Serializer
api = Red_Print('token')
@api.route('', methods=['POST'])
def get_token():
data = request.json
form = ClientForm(data=data).validate_for_api()
promise = {
ClientTypeEnum.USER_EMAIL: __vertify_cate_email,
ClientTypeEnum.USER_MOBILE: __vertify_cate_mobile,
ClientTypeEnum.USER_MINA: __vertify_cate_mina,
}
identity = promise[form.type.data](form)
user = identity['user']
uid = user.id
int_type = form.type.data.value
scope = ''
token = generate_auth_token(uid, int_type, scope).decode("utf8")
return jsonify({"token": token})
def generate_auth_token(uid, int_type, scope=None, expiration=7200):
s = Serializer(current_app.config['SECRET_KEY'], expires_in=expiration)
data_dict = dict(
uid=uid,
int_type=int_type,
scope=''
)
token_data = s.dumps(data_dict)
return token_data
def __vertify_cate_email(form):
result = User.vertify_user_password(form.account.data, form.password.data)
return result
def __vertify_cate_mobile():
pass
def __vertify_cate_mina():
pass
2.带着token访问资源
用到flask_httpauth模块
app/libs/auth_token.py
from flask_httpauth import HTTPBasicAuth
from itsdangerous import TimedJSONWebSignatureSerializer as Serializer
from itsdangerous import BadSignature, SignatureExpired
from flask import current_app, g, request
from app.libs.error_code import AuthFail, My_notfound
from collections import namedtuple
from base64 import b64decode
from functools import wraps
User = namedtuple('User', ['uid','int_type','scope'])
auth = HTTPBasicAuth()
@auth.verify_password
def vertify_password(account_or_token, password):
user = checked_token(account_or_token)
if not user:
return False
else:
g.user = user
return True
def checked_token(token):
s = Serializer(current_app.config['SECRET_KEY'])
try:
data_dict = s.loads(token.encode('utf8'))
except SignatureExpired as e:
raise AuthFail(msg='token is expired')
except BadSignature as e:
raise AuthFail(msg='token is valid')
uid = data_dict['uid']
int_type = data_dict['int_type']
scope = data_dict['scope']
user = User(uid, int_type, scope)
return user
app/v1/user.py
from flask import g
from app.libs.red_print import Red_Print
from app.libs.auth_token import auth, decorator
from flask import jsonify
api = Red_Print('user')
@api.route('', methods=['POST'])
@auth.login_required # 此处验证工作交由app/libs/auth_token.py中的vertify_password方法完成
def get_user():
user = g.user
return jsonify(user)
3.自定义验证装饰器
app/libs/auth_token.py
...
from base64 import b64decode
from functools import wraps
def checked_token(token):
...
...
def decorator(func):
@wraps(func)
def inner(*args, **kwargs):
print(request.headers)
_b64token = request.headers.get('Authorization')
b64token = _b64token.split(' ')[1]
token = b64decode(b64token)
token = token.decode('utf8').replace(":","")
user = checked_token(token)
if not user:
raise My_notfound()
else:
g.user = user
return func(*args, **kwargs)
return inner
app/v1/user.py
from flask import g
from app.libs.red_print import Red_Print
from app.libs.auth_token import decorator
from flask import jsonify
api = Red_Print('user')
@api.route('', methods=['POST'])
@decorator
def get_user():
user = g.user
return jsonify(user)