面试题答案
一键面试基于角色的访问控制(RBAC)模型概念
RBAC是一种广泛应用的访问控制策略,它基于用户在系统中所扮演的角色来管理对资源的访问权限。在RBAC模型中有三个主要元素:
- 用户(User):使用系统的个体。
- 角色(Role):代表一组权限的集合,一个角色可以被赋予多个权限,一个用户可以拥有多个角色。
- 权限(Permission):定义了对特定资源的特定操作,如读取文件、写入数据库记录等。
在Python的FastAPI中使用数据库实现RBAC模型
1. 数据结构设计
以SQLite为例,使用SQLAlchemy
库来定义数据库模型,SQLAlchemy
同样适用于MySQL等其他数据库。
from sqlalchemy import create_engine, Column, Integer, String, ForeignKey
from sqlalchemy.orm import sessionmaker, relationship
from sqlalchemy.ext.declarative import declarative_base
# 创建数据库引擎
engine = create_engine('sqlite:///rbac.db')
Session = sessionmaker(bind=engine)
Base = declarative_base()
# 定义权限表
class Permission(Base):
__tablename__ = 'permissions'
id = Column(Integer, primary_key=True)
name = Column(String(50), unique=True)
description = Column(String(200))
# 定义角色表
class Role(Base):
__tablename__ = 'roles'
id = Column(Integer, primary_key=True)
name = Column(String(50), unique=True)
permissions = relationship('Permission', secondary='role_permissions')
# 角色 - 权限关联表
class RolePermission(Base):
__tablename__ = 'role_permissions'
role_id = Column(Integer, ForeignKey('roles.id'), primary_key=True)
permission_id = Column(Integer, ForeignKey('permissions.id'), primary_key=True)
# 定义用户表
class User(Base):
__tablename__ = 'users'
id = Column(Integer, primary_key=True)
username = Column(String(50), unique=True)
roles = relationship('Role', secondary='user_roles')
# 用户 - 角色关联表
class UserRole(Base):
__tablename__ = 'user_roles'
user_id = Column(Integer, ForeignKey('users.id'), primary_key=True)
role_id = Column(Integer, ForeignKey('roles.id'), primary_key=True)
2. FastAPI实现RBAC功能
from fastapi import FastAPI, Depends
from sqlalchemy.orm import Session
from typing import List
app = FastAPI()
# 获取数据库会话的依赖项
def get_db():
db = Session()
try:
yield db
finally:
db.close()
# 创建用户
@app.post('/users/')
def create_user(username: str, db: Session = Depends(get_db)):
new_user = User(username=username)
db.add(new_user)
db.commit()
db.refresh(new_user)
return new_user
# 创建角色
@app.post('/roles/')
def create_role(name: str, db: Session = Depends(get_db)):
new_role = Role(name=name)
db.add(new_role)
db.commit()
db.refresh(new_role)
return new_role
# 为角色添加权限
@app.post('/roles/{role_id}/permissions/')
def add_permission_to_role(role_id: int, permission_name: str, db: Session = Depends(get_db)):
role = db.query(Role).filter(Role.id == role_id).first()
permission = db.query(Permission).filter(Permission.name == permission_name).first()
if not role or not permission:
return {"message": "Role or Permission not found"}
role.permissions.append(permission)
db.commit()
return {"message": "Permission added to role successfully"}
# 为用户添加角色
@app.post('/users/{user_id}/roles/')
def add_role_to_user(user_id: int, role_id: int, db: Session = Depends(get_db)):
user = db.query(User).filter(User.id == user_id).first()
role = db.query(Role).filter(Role.id == role_id).first()
if not user or not role:
return {"message": "User or Role not found"}
user.roles.append(role)
db.commit()
return {"message": "Role added to user successfully"}
# 检查用户权限
@app.get('/users/{user_id}/has_permission/{permission_name}/')
def check_user_permission(user_id: int, permission_name: str, db: Session = Depends(get_db)):
user = db.query(User).filter(User.id == user_id).first()
if not user:
return {"message": "User not found"}
for role in user.roles:
for permission in role.permissions:
if permission.name == permission_name:
return {"has_permission": True}
return {"has_permission": False}
以上代码展示了在FastAPI应用中,如何使用SQLite数据库(通过SQLAlchemy
)来实现RBAC模型的基本功能,包括用户、角色、权限以及它们之间的关联关系,以及如何通过API接口来操作这些数据。对于MySQL数据库,只需修改create_engine
的连接字符串即可,其余代码逻辑基本不变。