#sqlx #session #axum #tower

已删除 axum_sqlx_session_auth

提供用户身份验证和权限令牌检查的库。它需要AxumSQLxSessions库和Tower_cookies库。

0.1.1 2021年12月6日
0.1.0 2021年11月19日

#120 in #tower

MIT 许可证

17KB
246 代码行

axum_sqlx_session_auth

提供用户身份验证和权限令牌检查的库。它需要AxumSQLxSessions库和Tower_cookies库。此库将帮助确保用户ID或授权不存储在客户端,而是存储在服务器端。授权通过存储在客户端的客户端服务器端会话ID进行链接。

https://crates.io/crates/axum_sqlx_session_auth Docs

示例

pub fn init_pool(config: &ServerConfig) -> anyhow::Result<sqlx::Pool<sqlx::Postgres>> {
    let mut connect_opts = PgConnectOptions::new();
    connect_opts.log_statements(LevelFilter::Debug);
    connect_opts = connect_opts.database(&config.pgsql_database[..]);
    connect_opts = connect_opts.username(&config.pgsql_user[..]);
    connect_opts = connect_opts.password(&config.pgsql_password[..]);
    connect_opts = connect_opts.host(&config.pgsql_host[..]);
    connect_opts = connect_opts.port(config.pgsql_port);

    let pool = block_on(
        PgPoolOptions::new()
            .max_connections(5)
            .connect_with(connect_opts),
    )?;

    Ok(pool)
}

#[tokio::main]
async fn main() {
    // Set the RUST_LOG, if it hasn't been explicitly defined
    if std::env::var_os("RUST_LOG").is_none() {
        std::env::set_var("RUST_LOG", "example_templates=debug,tower_http=debug")
    }
    tracing_subscriber::fmt::init();

    let config = //load your config here.
    let poll = init_pool(&config).unwrap();

    let session_config = SqlxSessionConfig::default()
        .with_database("test")
        .with_table_name("test_table");

    // build our application with some routes
    let app = Router::new()
        .route("/greet/:name", get(greet))
        .layer(tower_cookies::CookieManagerLayer::new())
        .layer(SqlxSessionLayer::new(session_config, poll.clone()))
        .layer(AuthSessionLayer::new(poll.clone(), Some(1)))

    // run it
    let addr = SocketAddr::from(([127, 0, 0, 1], 3000));
    tracing::debug!("listening on {}", addr);
    axum::Server::bind(&addr)
        .serve(app.into_make_service())
        .await
        .unwrap();
}

//we can get the Method to compare with what Methods we allow. Useful if thius supports multiple methods.
//When called auth is loaded in the background for you.
async fn greet(method: Method, session: SQLxSession, auth: AuthSession<User>) -> &'static str {
    let mut count: usize = session.get("count").unwrap_or(0);
    count += 1;
    session.set("count", count);

    if let Some(cur_user) = current_user {
        if !Auth::<User>::build(&[Method::Get], false)
            .requires(Rights::none(&[
                Rights::Permission("Token::UseAdmin".into()),
                Rights::Permission("Token::ModifyPerms".into()),
            ]))
            .validate(&cur_user, &method, None)
            .await
        {
            return format!("No Permissions! for {}", cur_user.username)[];
        }

        let username = if !auth.is_authenticated() {
            //Set the user ID of the User to the Session so it can be Auto Loaded the next load or redirect
            auth.login_user(2);
            "".to_string()
        } else {
            //if the user is loaded and is Authenticated then we can use it.
            if let Some(user) = auth.current_user {
                user.username.clone()
            } else {
                "".to_string()
            }
        };

        format!("{}-{}", username, count)[..]
    } else {
        if !auth.is_authenticated() {
            //Set the user ID of the User to the Session so it can be Auto Loaded the next load or redirect
            auth.login_user(2);
            //redirect here after login if we did indeed login.
        }

        "No Permissions!"
    }
}

#[derive(Debug)]
pub struct User {
    pub id: i32,
    pub anonymous: bool,
    pub username: String,
}

//This is only used if you want to use Token based Authentication checks
#[async_trait]
impl HasPermission for User {
    async fn has(&self, perm: &String, pool: &Option<&mut PoolConnection<sqlx::Postgres>>) -> bool {
        match &perm[..] {
            "Token::UseAdmin" => true,
            "Token::ModifyUser" => true,
            _ => false,
        }
    }
}

#[async_trait]
impl SQLxSessionAuth<User> for User {
    async fn load_user(userid: i64, _pool: Option<&mut PoolConnection<sqlx::Postgres>>) -> Result<User> {
        Ok(User {
            id: userid,
            anonymous: true,
            username: "Guest".to_string(),
        })
    }

    fn is_authenticated(&self) -> bool {
        !self.anonymous
    }

    fn is_active(&self) -> bool {
        !self.anonymous
    }

    fn is_anonymous(&self) -> bool {
        self.anonymous
    }
}

依赖项

~26–39MB
~722K SLoC