Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

RBAC 权限管理

Feature: rbac

基于角色的访问控制(Role-Based Access Control)。通过 RbacStore trait 抽象存储层,用户自行实现具体存储逻辑(数据库、Redis、内存等)。

设计

  • RbacStore:存储 trait,定义权限检查、角色管理等接口
  • Rbac:对外 API,持有 Arc<dyn RbacStore>
  • 数据模型RoleUserRole 等通用结构

使用

1. 实现 RbacStore trait

#![allow(unused)]
fn main() {
use afaster::rbac::{RbacStore, Role};
use afaster::Result;
use std::future::Future;
use std::pin::Pin;

struct MyRbacStore {
    pool: sqlx::SqlitePool,
}

impl RbacStore for MyRbacStore {
    fn check_permission(
        &self,
        user_id: i64,
        permission_code: &str,
    ) -> Pin<Box<dyn Future<Output = Result<bool>> + Send + '_>> {
        Box::pin(async move {
            let count: (i64,) = sqlx::query_as(
                "SELECT COUNT(*) FROM user_roles ur
                 JOIN role_permissions rp ON ur.role_id = rp.role_id
                 WHERE ur.user_id = ? AND rp.permission_code = ?",
            )
            .bind(user_id)
            .bind(permission_code)
            .fetch_one(&self.pool)
            .await
            .map_err(|e| afaster::Error::custom(52803, format!("{}", e)))?;
            Ok(count.0 > 0)
        })
    }

    // ... 实现其他方法
}
}

2. 创建 Rbac 实例

#![allow(unused)]
fn main() {
let rbac = Rbac::new(MyRbacStore { pool });
}

3. 配合 AFaster 使用

#![allow(unused)]
fn main() {
AFaster::new("config.toml".to_string()).await
    .unwrap()
    .set_rbac(rbac)
    .run()
    .await;
}

4. 在 handler 中使用

#![allow(unused)]
fn main() {
#[handler]
async fn create_post(
    State(state): State<AppState>,
    Ctx(ctx): Ctx<AuthData>,
) -> Result<Json<Post>> {
    let user_id = ctx.user_id;
    let rbac = state.rbac.as_ref().unwrap();

    // 检查权限
    if !rbac.check_permission(user_id, "post:create").await? {
        return Err(afaster::Error::custom(42803, "权限不足"));
    }

    // ...
}
}

RbacStore trait 方法

方法参数返回说明
check_permission(user_id, code)i64, &strResult<bool>检查用户是否有某权限
get_user_permissions(user_id)i64Result<Vec<String>>获取用户所有权限码
get_user_roles(user_id)i64Result<Vec<Role>>获取用户所有角色
assign_role(user_id, role_name)i64, &strResult<()>分配角色
remove_role(user_id, role_name)i64, &strResult<()>移除角色
create_role(name, display, perms)&str, &str, &[&str]Result<i64>创建角色
delete_role(name)&strResult<()>删除角色
get_role(name)&strResult<Role>获取角色详情
list_roles()Result<Vec<Role>>列出所有角色
get_role_permissions(role_id)i64Result<Vec<String>>获取角色的权限码
get_role_id(name)&strResult<i64>获取角色 ID

错误码

English中文
42801Role not found角色不存在
42802Cannot delete default role不能删除默认角色
42803Permission denied权限不足
52803Check failed权限检查失败
52804Assign failed角色分配失败
52805Role create failed角色创建失败