本文目录导读:

- 使用JWT (JSON Web Token) - 最推荐
- 使用
itsdangerous- Flask常用 - 使用
hashlib+ 随机数 - 简单实现 - Flask-JWT-Extended示例(完整Web应用)
- 安全建议
- 选择建议
我来介绍几种在Python中生成登录令牌的常见方法:
使用JWT (JSON Web Token) - 最推荐
安装依赖
pip install pyjwt
生成JWT令牌
import jwt
import datetime
from typing import Dict, Optional
# 密钥配置
SECRET_KEY = "your-secret-key-here"
ALGORITHM = "HS256"
def create_access_token(
data: Dict,
expires_delta: Optional[datetime.timedelta] = None
) -> str:
"""生成访问令牌"""
to_encode = data.copy()
if expires_delta:
expire = datetime.datetime.utcnow() + expires_delta
else:
# 默认24小时过期
expire = datetime.datetime.utcnow() + datetime.timedelta(hours=24)
to_encode.update({"exp": expire})
token = jwt.encode(to_encode, SECRET_KEY, algorithm=ALGORITHM)
return token
def verify_token(token: str) -> Dict:
"""验证令牌"""
try:
payload = jwt.decode(token, SECRET_KEY, algorithms=[ALGORITHM])
return payload
except jwt.ExpiredSignatureError:
raise Exception("Token已过期")
except jwt.InvalidTokenError:
raise Exception("无效的Token")
# 使用示例
def login(username: str, password: str) -> str:
"""登录函数"""
# 这里应该是验证用户名和密码的逻辑
if username == "admin" and password == "123456":
token_data = {
"sub": username, # 用户标识
"user_id": 1,
"role": "admin"
}
token = create_access_token(
data=token_data,
expires_delta=datetime.timedelta(hours=2)
)
return token
else:
raise Exception("用户名或密码错误")
# 测试
if __name__ == "__main__":
# 登录
try:
token = login("admin", "123456")
print(f"生成的Token: {token}")
# 验证Token
payload = verify_token(token)
print(f"Token解析结果: {payload}")
except Exception as e:
print(f"错误: {e}")
使用 itsdangerous - Flask常用
安装
pip install itsdangerous
示例代码
from itsdangerous import TimedJSONWebSignatureSerializer as Serializer
from itsdangerous import BadSignature, SignatureExpired
class TokenManager:
def __init__(self, secret_key: str, expires_in: int = 3600):
"""
:param secret_key: 密钥
:param expires_in: 过期时间(秒)
"""
self.secret_key = secret_key
self.expires_in = expires_in
self.serializer = Serializer(
secret_key=secret_key,
expires_in=expires_in
)
def generate_token(self, user_data: dict) -> str:
"""生成令牌"""
return self.serializer.dumps(user_data).decode('utf-8')
def verify_token(self, token: str) -> dict:
"""验证令牌"""
try:
data = self.serializer.loads(token)
return data
except SignatureExpired:
raise Exception("Token已过期")
except BadSignature:
raise Exception("无效的Token")
# 使用示例
token_manager = TokenManager(
secret_key="my-secret-key",
expires_in=7200 # 2小时
)
# 生成Token
user_info = {"user_id": 123, "username": "john"}
token = token_manager.generate_token(user_info)
print(f"生成的Token: {token}")
# 验证Token
try:
data = token_manager.verify_token(token)
print(f"验证成功: {data}")
except Exception as e:
print(f"验证失败: {e}")
使用 hashlib + 随机数 - 简单实现
import hashlib
import random
import string
import time
import json
import base64
class SimpleToken:
def __init__(self, secret_key: str):
self.secret_key = secret_key
def generate_token(self, user_id: int, username: str) -> str:
"""生成简单令牌"""
# 创建payload
payload = {
"user_id": user_id,
"username": username,
"timestamp": int(time.time()),
"random": ''.join(random.choices(string.ascii_letters + string.digits, k=8))
}
# 将payload转为JSON并编码
payload_str = json.dumps(payload, sort_keys=True)
payload_b64 = base64.b64encode(payload_str.encode()).decode()
# 生成签名
signature = hashlib.sha256(
f"{payload_b64}{self.secret_key}".encode()
).hexdigest()
# 组合Token
token = f"{payload_b64}.{signature}"
return token
def verify_token(self, token: str) -> dict:
"""验证令牌"""
try:
payload_b64, signature = token.split('.')
# 验证签名
expected_signature = hashlib.sha256(
f"{payload_b64}{self.secret_key}".encode()
).hexdigest()
if signature != expected_signature:
raise Exception("Token签名无效")
# 解码payload
payload_str = base64.b64decode(payload_b64).decode()
payload = json.loads(payload_str)
# 检查过期时间(这里设置24小时过期)
current_time = int(time.time())
if current_time - payload['timestamp'] > 86400:
raise Exception("Token已过期")
return payload
except (ValueError, json.JSONDecodeError):
raise Exception("无效的Token格式")
# 使用示例
token_mgr = SimpleToken("my-secret-key")
# 生成Token
token = token_mgr.generate_token(1, "john_doe")
print(f"生成的Token: {token}")
# 验证Token
try:
data = token_mgr.verify_token(token)
print(f"验证成功: {data}")
except Exception as e:
print(f"验证失败: {e}")
Flask-JWT-Extended示例(完整Web应用)
from flask import Flask, request, jsonify
from flask_jwt_extended import (
JWTManager, create_access_token, jwt_required,
get_jwt_identity, create_refresh_token
)
from datetime import timedelta
app = Flask(__name__)
# 配置
app.config['JWT_SECRET_KEY'] = 'super-secret-key'
app.config['JWT_ACCESS_TOKEN_EXPIRES'] = timedelta(hours=1)
app.config['JWT_REFRESH_TOKEN_EXPIRES'] = timedelta(days=30)
jwt = JWTManager(app)
# 模拟用户数据
users = {
"admin": {"password": "123456", "role": "admin"},
"user": {"password": "password", "role": "user"}
}
@app.route('/login', methods=['POST'])
def login():
username = request.json.get('username')
password = request.json.get('password')
if not username or not password:
return jsonify({"msg": "需要用户名和密码"}), 400
user = users.get(username)
if not user or user['password'] != password:
return jsonify({"msg": "用户名或密码错误"}), 401
# 创建访问令牌和刷新令牌
access_token = create_access_token(
identity=username,
additional_claims={"role": user['role']}
)
refresh_token = create_refresh_token(identity=username)
return jsonify({
"access_token": access_token,
"refresh_token": refresh_token
}), 200
@app.route('/protected', methods=['GET'])
@jwt_required()
def protected():
current_user = get_jwt_identity()
return jsonify({
"message": f"欢迎 {current_user}!",
"user": current_user
}), 200
@app.route('/refresh', methods=['POST'])
@jwt_required(refresh=True)
def refresh():
current_user = get_jwt_identity()
new_token = create_access_token(identity=current_user)
return jsonify({"access_token": new_token}), 200
if __name__ == '__main__':
app.run(debug=True)
安全建议
- 使用HTTPS:始终在HTTPS下传输Token
- 设置合理的过期时间:避免Token长期有效
- 存储敏感信息:不要在Token中存储密码等敏感信息
- 密钥管理:保密JWT密钥,使用环境变量存储
- Token吊销:实现Token黑名单机制
选择建议
- 生产环境:推荐使用JWT (pyjwt)
- Flask应用:推荐Flask-JWT-Extended
- 简单需求:可以使用itsdangerous
- 学习目的:可以使用hashlib实现
这些方法各有优劣,根据你的具体需求选择合适的方案。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播