如何用flask_restful结合flask_jwt_extended实现三类用户认证?
Flask-RESTful + Flask-JWT-Extended 多角色认证实现方案
一、完善User模型(models.py)
先在模型中明确用户角色字段,用枚举类型约束可选值,避免字符串拼写错误:
from flask_sqlalchemy import SQLAlchemy from enum import Enum from werkzeug.security import generate_password_hash, check_password_hash db = SQLAlchemy() class UserRole(Enum): USER = "user" # 普通会员 CREATOR = "creator" # 创作者 ADMIN = "admin" # 管理员 class User(db.Model): id = db.Column(db.Integer, primary_key=True) username = db.Column(db.String(80), unique=True, nullable=False) password_hash = db.Column(db.String(120), nullable=False) role = db.Column(db.Enum(UserRole), default=UserRole.USER, nullable=False) # 密码加密与验证方法 def set_password(self, password): self.password_hash = generate_password_hash(password) def check_password(self, password): return check_password_hash(self.password_hash, password)
二、初始化JWT与核心组件
在项目入口文件(比如app.py)完成Flask、JWT、数据库的初始化:
from flask import Flask from flask_restful import Api from flask_jwt_extended import JWTManager from models import db app = Flask(__name__) # 数据库配置,根据实际情况修改 app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///auth.db' # 生产环境务必用环境变量存储密钥 app.config['JWT_SECRET_KEY'] = 'your-secure-secret-key' db.init_app(app) jwt = JWTManager(app) api = Api(app) # 创建数据库表(首次运行用) with app.app_context(): db.create_all()
三、登录接口:返回带角色的Token(resource.py)
登录时验证用户身份,将角色信息存入JWT的额外声明,方便后续权限校验:
from flask_restful import Resource, reqparse from flask_jwt_extended import create_access_token from models import User class Login(Resource): def post(self): parser = reqparse.RequestParser() parser.add_argument('username', required=True, help='用户名不能为空') parser.add_argument('password', required=True, help='密码不能为空') args = parser.parse_args() user = User.query.filter_by(username=args['username']).first() if not user or not user.check_password(args['password']): return {'message': '用户名或密码错误'}, 401 # 将角色信息加入Token的额外声明 additional_claims = {'role': user.role.value} access_token = create_access_token(identity=user.id, additional_claims=additional_claims) return {'access_token': access_token}, 200 api.add_resource(Login, '/login')
四、自定义角色校验装饰器
封装装饰器,快速校验接口访问者的角色权限:
from functools import wraps from flask_jwt_extended import get_jwt def role_required(*required_roles): def decorator(f): @wraps(f) def decorated_function(*args, **kwargs): jwt_data = get_jwt() user_role = jwt_data.get('role') if user_role not in required_roles: return {'message': '权限不足'}, 403 return f(*args, **kwargs) return decorated_function return decorator
五、多角色接口示例(resource.py)
结合jwt_required和自定义装饰器,实现不同角色的接口访问控制:
from flask_jwt_extended import jwt_required, get_jwt_identity from models import User, db # 普通会员、创作者、管理员均可访问 class UserProfile(Resource): @jwt_required() @role_required('user', 'creator', 'admin') def get(self): user_id = get_jwt_identity() user = User.query.get(user_id) return {'username': user.username, 'role': user.role.value}, 200 # 仅创作者、管理员可访问(比如发布内容接口) class CreatorContent(Resource): @jwt_required() @role_required('creator', 'admin') def post(self): # 此处添加内容发布逻辑 return {'message': '内容发布成功'}, 201 # 仅管理员可访问(比如删除用户接口) class AdminUserManage(Resource): @jwt_required() @role_required('admin') def delete(self, user_id): user = User.query.get(user_id) if not user: return {'message': '用户不存在'}, 404 db.session.delete(user) db.session.commit() return {'message': '用户已删除'}, 200 api.add_resource(UserProfile, '/profile') api.add_resource(CreatorContent, '/creator/content') api.add_resource(AdminUserManage, '/admin/user/<int:user_id>')
六、Vue3前端配合要点
- 登录成功后,将后端返回的
access_token存入localStorage或状态管理工具(如Pinia) - 发起接口请求时,在请求头中携带
Authorization: Bearer ${token} - 根据后端返回的角色信息,控制前端页面元素的显示/隐藏(比如仅管理员可见用户管理菜单)
- 统一处理401(Token过期/无效)和403(权限不足)状态码,比如跳转登录页或弹出权限提示
内容的提问来源于stack exchange,提问作者niksy
相关产品推荐
相关产品推荐

