Flask 實現HTTP令牌token認證HTTPTokenAuth


前言

  • 命名文件不要用“token.py”,會報無法導入xxx類等異常
  • 在restful設計中,用戶認證模式通常使用json web token,而不會使用傳統的HTTP Basic認證(傳入賬號密碼)
  • token認證模式如下:在請求header中加入token(傳入賬號密碼)

Flask中的實現

flask擴展flask-httpauth提供了該認證方法

$ pip install flask-httpauth

首先實例化

auth = HTTPTokenAuth(scheme='JWT')

校驗token的方法(token_auth.py)

from flask_httpauth import HTTPTokenAuth
from itsdangerous import TimedJSONWebSignatureSerializer as Serializer, BadSignature, SignatureExpired

from config import Config
from home.libs.error_code import AuthFailed

auth = HTTPTokenAuth(scheme='JWT')


@auth.verify_token
def verify_token(token):
    # Config.SECRET_KEY:內部的私鑰,這里寫在配置信息里
    s = Serializer(Config.SECRET_KEY)
    try:
        data = s.loads(token)
    except BadSignature:
        # AuthFailed 自定義的異常類型
        raise AuthFailed(msg='token不正確')
    except SignatureExpired:
        raise AuthFailed(msg='token過期')
    # 校驗通過返回True
    return True

生成token的方法,放在了modeles.user類中生成

from config import Config
from home import db
from werkzeug.security import generate_password_hash, check_password_hash
from itsdangerous import TimedJSONWebSignatureSerializer as Serializer



class User(db.Model):
    """用戶"""

    __tablename__ = 'user'

    id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    username = db.Column(db.String(80), unique=True, nullable=False) # 用戶名
    hash_password = db.Column(db.String(120), nullable=False)        # 密碼
    phone = db.Column(db.String(20), nullable=False)                 # 手機號

    # 明文密碼(只讀)
    @property
    def password(self):
        raise AttributeError('不可讀')

    # 寫入密碼,同時計算hash值,保存到模型中
    @password.setter
    def password(self,value):
        self.hash_password = generate_password_hash(value)

    # 檢查密碼是否正確
    def check_password(self, password):
        return check_password_hash(self.hash_password,password)

    # 生成token
    @staticmethod
    def create_token(user_id):
        """
        生成token
        :param user_id: 用戶id
        :return:
        """

        # 第一個參數是內部的私鑰,這里寫在配置信息里,如果只是測試可以寫死
        # 第二個參數是有效期(秒)
        s = Serializer(Config.SECRET_KEY, expires_in=Config.TOKEN_EXPIRATION)
        # 接收用戶id轉換與編碼
        token = s.dumps({"id": user_id}).decode('ascii')
        return token

使用裝飾器

from flask import request, jsonify

from home.modles import User


@api.route('/login', methods=['POST'])
def login():
    '''
    接受參數並校驗參數,返回token
    :return: 
    '''
    # user = request.json['username']
    # password = request.json['password']
    # guest = User.query.filter_by(username=user).first()
    # # 生成token
    # z_token = User.create_token(guest.id)
    # 
    # return jsonify(token=z_token)
    pass



# 調用該裝飾器認證token(導入token_auth.py中的auth:from home.utils.token_auth import auth)
@api.route('/index')
@auth.login_required  
def index():
    return 'helllo word'


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM