fastapi搭建平台实战教程三:接口编写及权限校验(前后端分离)
首先需要分组表、用户表加入映射关系,然后分组表加入权限组字段·。
class InfoCrud(Base): __abstract__ = True # 作为父类使用,并且不在数据库生成此表 _create_time = Column('create_time', DateTime, default=datetime.now) update_time = Column(DateTime, default=datetime.now, onupdate=datetime.now) delete_time = Column(DateTime) update_user_id = Column(Integer, nullable=True) create_user_id = Column(Integer, nullable=True) update_user_name = Column(String(50), nullable=True) create_user_name = Column(String(50), nullable=True) class Group(InfoCrud): __tablename__ = 'group' id = Column(Integer, primary_key=True) # : name of group # : 权限组名称 name = Column(String(60), comment="权限组名称") # a description of a group # 权限组描述 info = Column(String(255), comment="权限组描述") users = relationship("User",backref="user_group") auths = Column(String(255), comment="权限组描述",default="[]") class User(InfoCrud): __tablename__ = "user" # 数据库表名 id = Column(Integer,primary_key=True) username = Column(String(24), nullable=False, unique=True, comment="昵称") password = Column(String(500), nullable=False, comment="密码") nickname = Column(String(100),nullable=True, comment="用户姓名") email = Column(String(100), nullable=True, comment="电子邮箱") isadmin = Column(Boolean,default=False,comment="管理员") group_id = Column(ForeignKey("group.id"),default=1) class Auth(InfoCrud): __tablename__ = 'auth' id = Column(Integer, primary_key=True) # : 权限字段 auth = Column(String(60), comment="权限字段") # : 权限的模块 url = Column(String(60), comment="路由")
不会使用Alembic的话,需要手动更新数据库。也可以删除重建。
main.py修改注册用户参数
...
class RegisterForm(BaseModel): username: str password: str group_id: int @app.post("/register") def register(user: RegisterForm): if SessionLocal().query(models.User).filter_by(username=user.username).count() > 0: return JSONResponse({ "code": 400, "msg": "用户已存在" }) db_user = models.User(username=user.username, password=get_password_hash(user.password),group_id=user.group_id) with SessionLocal.begin() as session: session.add(db_user) return JSONResponse({ "code": 0, "msg": "注册成功" })
编写添加权限及添加分组接口
...
class AuthForm(BaseModel): auth: str url: str @app.post("/auth/add") async def auth_add(form:AuthForm): db_group = models.Auth(auth=form.auth, url=form.url) with SessionLocal.begin() as session: session.add(db_group) return JSONResponse({ "code": 0, "msg": "新增成功" }) class GroupForm(BaseModel): name: str info: str @app.post("/group/add") async def group_add(form:GroupForm): db_group = models.Group(name=form.name, info=form.info) with SessionLocal.begin() as session: session.add(db_group) return JSONResponse({ "code": 0, "msg": "新增成功" })
auth.py添加校验用户权限的依赖方法
def get_auth(request:Request,current_user: models.User = Depends(get_current_user)): group = SessionLocal().query(models.Group).get(current_user.group_id) auths = [] for aid in json.loads(group.auths): auths.append(SessionLocal().query(models.Auth).get(aid).url) if request.url.path not in auths: raise HTTPException( status_code=status.HTTP_401_UNAUTHORIZED, detail="权限不够,请联系超级管理员获得权限" )
给一个接口添加教研
... @app.get("/users/info", response_model=UserRes,dependencies=[Depends(get_auth)]) ...
依次添加分组,用户,权限后,登录获取token,请求/users/info,默认没有权限,使用curl请求接口会返回
main.py添加编辑分组权限的接口,并编辑分组的auths为[1]
...
class Group(GroupForm): id: int auths: list[int] = [] @app.post("/group/editauth") async def group_editauth(form:Group): with SessionLocal.begin() as session: db_group = session.query(models.Group).get(form.id) db_group.name = form.name db_group.info = form.info db_group.auths = json.dumps(form.auths) session.commit() return JSONResponse({ "code": 0, "msg": "更新成功" })
再次请求/users/info会返回数据
至此fastapi用户管理及权限验证的后台接口基本后端框架就完成了,还有一些细节需要自己去改进,然后就是根据这个逻辑选择前端框架编写前端页面。