实现思路
- 用户注册:创建注册页面表单,接收用户输入的信息(如用户名、密码等),验证信息合法性后将用户信息存储到数据库。
- 用户登录:创建登录页面表单,接收用户输入的用户名和密码,与数据库中存储的信息进行比对,验证成功则生成并返回认证令牌(如JWT)。
- 权限授权:在数据库中为每个用户记录权限信息。在需要权限控制的路由上,通过中间件或装饰器检查用户令牌,解析出用户权限,判断是否有权限访问该路由。
- 密码安全存储:使用强哈希算法(如bcrypt)对用户密码进行哈希处理后存储,验证密码时使用相同算法比对哈希值。
关键代码片段
- 安装必要的库
pip install flask flask_sqlalchemy flask_bcrypt flask_jwt_extended
- 定义数据库模型
from flask_sqlalchemy import SQLAlchemy
from flask_bcrypt import Bcrypt
db = SQLAlchemy()
bcrypt = Bcrypt()
class User(db.Model):
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(50), unique=True, nullable=False)
password = db.Column(db.String(100), nullable=False)
role = db.Column(db.String(20), nullable=False) # 权限字段
- 用户注册
from flask import Flask, request, jsonify
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] ='sqlite:///users.db'
db.init_app(app)
bcrypt.init_app(app)
@app.route('/register', methods=['POST'])
def register():
data = request.get_json()
hashed_password = bcrypt.generate_password_hash(data['password']).decode('utf-8')
new_user = User(username=data['username'], password=hashed_password, role=data['role'])
db.session.add(new_user)
db.session.commit()
return jsonify({'message': 'User registered successfully'}), 201
- 用户登录
from flask_jwt_extended import create_access_token
@app.route('/login', methods=['POST'])
def login():
data = request.get_json()
user = User.query.filter_by(username=data['username']).first()
if user and bcrypt.check_password_hash(user.password, data['password']):
access_token = create_access_token(identity=user.id)
return jsonify({'access_token': access_token}), 200
return jsonify({'message': 'Invalid credentials'}), 401
- 权限控制装饰器
from functools import wraps
from flask_jwt_extended import get_jwt_identity, verify_jwt_in_request
from flask import abort
def requires_role(role):
def wrapper(fn):
@wraps(fn)
def decorator(*args, **kwargs):
verify_jwt_in_request()
user_id = get_jwt_identity()
user = User.query.get(user_id)
if user.role != role:
abort(403)
return fn(*args, **kwargs)
return decorator
return wrapper
- 需要权限的路由
@app.route('/admin/dashboard', methods=['GET'])
@requires_role('admin')
def admin_dashboard():
return jsonify({'message': 'This is an admin - only dashboard'}), 200
密码安全存储
- 哈希处理:使用
bcrypt.generate_password_hash
对用户输入的密码进行哈希处理,存储到数据库的是哈希后的字符串,而不是明文密码。
- 密码验证:在用户登录时,使用
bcrypt.check_password_hash
比对用户输入的密码和数据库中存储的哈希值,验证用户身份。