ruxt axum中使用casbin-rs

3 篇文章 0 订阅
2 篇文章 0 订阅

ruxt axum中使用casbin-rs


一、casbin-rs是什么?

casbin-rs是管理端rbac权限框架的rust抽象实现

二、使用步骤

1.引入库

代码如下(示例):

Cargo.toml中引入
casbin = "2.0.9"

2.核心service封装

代码如下(示例):
casbin_service.rs


#[derive(Clone)]
pub struct CasbinVals {
    pub uid: String,
    pub agency_code: Option<String>,
}

/**
 *struct:CasbinService
 *desc:casbin 权限处理核心service
 *author:String
 *email:348040933@qq.com
 */
#[derive(Clone)]
pub struct CasbinService {
    pub enforcer: Arc<RwLock<CachedEnforcer>>,
}

impl CasbinService {
    /**
    sign_in
     *method:default
     *desc:初始化casbin 上下文 加载model 初始化 CICIAdapter casbin适配器
     *author:String
     *email:348040933@qq.com
     */
    pub async fn default() -> Self {
        /*加载模型文件*/
        let m = DefaultModel::from_file("cassie_web/auth_config/rbac_with_domains_model.conf")
            .await
            .unwrap();
        info!("casbin模型文件加载完成!");

        let config = APPLICATION_CONTEXT.get::<ApplicationConfig>();
        //这里是自定义rbatis适配器 
        //https://gitee.com/stringlxd/cassie_axum/tree/master/cassie_casbin_adapte
        let a = CICIAdapter::new(init_rbatis(config).await);
        let mut cached_enforcer = CachedEnforcer::new(m, a).await.unwrap();
        /* 添加自定义验证方法 */
        cached_enforcer.add_function("ciciMatch", cici_match);
        info!("casbin init success");
        Self {
            enforcer: Arc::new(RwLock::new(cached_enforcer)),
        }
    }

    pub async fn new<M: TryIntoModel, A: TryIntoAdapter>(m: M, a: A) -> CasbinResult<Self> {
        let enforcer: CachedEnforcer = CachedEnforcer::new(m, a).await?;
        Ok(CasbinService {
            enforcer: Arc::new(RwLock::new(enforcer)),
        })
    }

    pub fn get_enforcer(&self) -> Arc<RwLock<CachedEnforcer>> {
        self.enforcer.clone()
    }

    pub fn set_enforcer(e: Arc<RwLock<CachedEnforcer>>) -> CasbinService {
        CasbinService { enforcer: e }
    }
    /**
     *method:call
     *desc:核心验证方法 path ,action ,vals
     *author:String
     *email:348040933@qq.com
     */
    pub async fn call(&self, path: String, action: String, vals: CasbinVals) -> bool {
        /*获取验证器*/
        let cloned_enforcer = self.get_enforcer();
        let uid = vals.uid.clone();
        /*获取对应的 用户 用户为空直接返回false*/
        if !vals.uid.is_empty() {
            /*判断是否是多租户模型*/
            let vecs = if let Some(agency_code) = vals.agency_code {
                vec![uid, agency_code, path, action]
            } else {
                vec![uid, path, action]
            };
            let mut lock = cloned_enforcer.write().await;
            match lock.enforce_mut(vecs) {
                Ok(true) => {
                    drop(lock);
                    true
                }
                Ok(false) => {
                    drop(lock);
                    false
                }
                Err(_) => {
                    drop(lock);
                    false
                }
            }
        } else {
            false
        }
    }
}
//初始化casbin_service

这里只是核心的代码封装


总结

以上只是cassie axum代码里的核心封装

在这里我们使用到的是CachedEnforcer,由于web项目的path
资源验证不可每次都查数据库 所以需要用到缓存
项目启动时加载

pub async fn init_casbin() {
    APPLICATION_CONTEXT.set::<CasbinService>(CasbinService::default().await);
}

初始化的时候是直接放到 全局的单例池里的
为什么要这么做呢 权限资源在项目启动的时候
首次加载到缓存里,后续管理端操作用户权限信息的
时候要同步到缓存里 所以要从单例池里能拿到才行

项目源码

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值