Flask實現token認證


1. 安裝

pip install flask_httpauth
pip install itsdangerous

2. 創建對象

from flask import Flask, g, jsonify from flask_httpauth import HTTPBasicAuth app = Flask(__name__) auth = HTTPBasicAuth() 

3. 生成token

from itsdangerous import TimedJSONWebSignatureSerializer as Serializer # 密鑰,可隨意修改 SECRET_KEY = 'abcdefghijklmm' # 生成token, 有效時間為600min def generate_auth_token(user_id, expiration=36000): # 第一個參數是內部私鑰 # 第二個參數是有效期(秒) s = Serializer(SECRET_KEY, expires_in=expiration) return s.dumps({'user_code': user_code}) 

4. 解析token

from itsdangerous import TimedJSONWebSignatureSerializer as Serializer from itsdangerous import BadSignature, SignatureExpired # 密鑰,可隨意修改 SECRET_KEY = 'abcdefghijklmm' # 解析token def verify_auth_token(token): s = Serializer(SECRET_KEY) # token正確 try: data = s.loads(token) return data # token過期 except SignatureExpired: return None # token錯誤 except BadSignature: return None 

5. 驗證token

# 數據庫配置 db = { 'host': '127.0.0.1', 'user': 'root', 'password': 'admin123', 'port': 3306, 'database': 'school', 'charset': 'utf8' } # 連接數據庫操作 def connect(user_id, password): conn = mc.connect(**db) cursor = conn.cursor(dictionary=True) args = (user_id, password) verify_sql = "SELECT user_id FROM account WHERE user_id = %s AND pwd = PASSWORD(%s);" cursor.execute(verify_sql, args) user = cursor.fetchone() return user # 驗證token @auth.verify_password def verify_password(username, password): # 先驗證token user_id = re.sub(r'^"|"$', '', username) user_id = verify_auth_token(user_id) # 如果token不存在,驗證用戶id與密碼是否匹配 if not user_id: user_id = connect(username, password) # 如果用戶id與密碼對應不上,返回False if not user_id: return False g.user_id = user_id.get('user_id') return True 

6. 完整代碼

配置文件config.py

# 數據庫配置
db = {
        'host': '127.0.0.1',
        'user': 'root',
        'password': 'admin123',
        'port': 3306,
        'database': 'school',
        'charset': 'utf8'
}

# 密鑰,可隨意修改
SECRET_KEY = 'abcdefghijklmm'

主文件run.py

from flask import Flask, g, jsonify from flask_httpauth import HTTPBasicAuth from itsdangerous import TimedJSONWebSignatureSerializer as Serializer from itsdangerous import BadSignature, SignatureExpired from flask_cors import CORS import mysql.connector as mc from config import db, SECRET_KEY import re app = Flask(__name__) CORS(app, supports_credentials=True) auth = HTTPBasicAuth() # 生成token, 有效時間為600min def generate_auth_token(user_id, expiration=36000): s = Serializer(SECRET_KEY, expires_in=expiration) return s.dumps({'user_id': user_id}) # 解析token def verify_auth_token(token): s = Serializer(SECRET_KEY) # token正確 try: data = s.loads(token) return data # token過期 except SignatureExpired: return None # token錯誤 except BadSignature: return None # 連接數據庫操作 def connect(user_id, password): conn = mc.connect(**db) cursor = conn.cursor(dictionary=True) args = (user_id, password) verify_sql = "SELECT user_id FROM account WHERE user_id = %s AND pwd = PASSWORD(%s);" cursor.execute(verify_sql, args) user = cursor.fetchone() return user # 驗證token @auth.verify_password def verify_password(username, password): # 先驗證token user_id = re.sub(r'^"|"$', '', username) user_id = verify_auth_token(user_id) # 如果token不存在,驗證用戶id與密碼是否匹配 if not user_id: user_id = connect(username, password) # 如果用戶id與密碼對應不上,返回False if not user_id: return False g.user_id = user_id.get('user_id') return True @app.route('/login') @auth.login_required def login(): token = generate_auth_token(g.user_id) return jsonify({'token': token}) @app.route('/index') @auth.login_required def index(): return 'index' if __name__ == '__main__': app.run() 

只需要在需要登錄驗證請求下添加裝飾器@auth.login_required即可

7. 測試

我這里使用到的數據庫是school其中的account
該表有兩個字段user_idpwd
先向表中添加一條數據進行測試
INSERT INTO account (user_id, password) VALUES("kun", PASSWORD("admin123"))

  • 直接輸入路由測試

返回401錯誤碼


 
 
  • 輸入錯誤的用戶名或者密碼測試

返回401錯誤碼


 
 
  • 輸入正確的用戶名以及密碼測試

輸入正確的用戶名以及密碼后,測試成功,獲取到token
前端可以將token存入到瀏覽器session
下次發請求加上token,即可通過驗證

 
 

 

  • 使用有效的token測試

使用剛才生成的token進行測試,測試成功


 
 
  • 使用過期的token或者錯誤的token測試

返回401錯誤碼


 
 

8. 總結

  1. flask_httpauth用於獲取請求中的Authorization參數
  2. itsdangerous用於生成以及驗證token
  3. SECRET_KEY密鑰可自行修改
  4. 用戶可以使用用戶密碼進行認證,或者使用token進行認證
  5. 在需要token認證的路由前添加@auth.login_required即可開啟認證
  6. 可以在before_request處理程序中使用@auth.login_required修飾器, 應用到所有請求



作者:無敵小魯班
鏈接:https://www.jianshu.com/p/a360473bc9ab


免責聲明!

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



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