#flex #user #passage #passkey #applications #verification

passage_flex

为使用Passage Passkey Flex的应用程序提供服务器端身份验证验证。

2个版本

新版本 0.1.1 2024年8月23日
0.1.0 2024年8月23日

#94身份验证

Download history 110/week @ 2024-08-17

123 每月下载量

MIT 许可证

125KB
2.5K SLoC

passage_flex

Passage logo

crates.io

Passkey Flex为现有身份验证系统提供密钥支持。它抽象了本地密钥API的复杂性,并提供了一个简单、干净的解决方案,将您的身份验证提升到下一个层次。

passage_flex Rust crate 允许验证使用 Passage Passkey Flex 的应用程序的服务器端身份验证。

有关完整文档,请访问 Passkey Flex 文档Docs.rs 页面。

安装

使用cargo安装此crate

cargo add passage_flex

创建一个PassageFlex实例

需要一个Passage AppID和API密钥。可以在Passage控制台中创建App和AppID,并在应用程序设置下创建API密钥。此API密钥允许访问Passage管理API以获取和更新有关用户的信息。此API密钥必须受到保护,并存储在适当的加密存储位置。它决不应该在仓库中硬编码。

use passage_flex::PassageFlex;

let passage_flex = PassageFlex::new(
    std::env::var("PASSAGE_APP_ID").unwrap(),
    std::env::var("PASSAGE_API_KEY").unwrap(),
);

检索应用程序信息

要检索有关应用程序的信息,请使用 get_app 方法。

use passage_flex::PassageFlex;

let passage_flex = PassageFlex::new(
    std::env::var("PASSAGE_APP_ID").unwrap(),
    std::env::var("PASSAGE_API_KEY").unwrap(),
);

let app_info = passage_flex.get_app().await.unwrap();
println!("{}", app_info.auth_origin);

创建注册事务

要创建启动用户密钥注册的事务,请使用 create_register_transaction 方法。

use passage_flex::PassageFlex;

let passage_flex = PassageFlex::new(
    std::env::var("PASSAGE_APP_ID").unwrap(),
    std::env::var("PASSAGE_API_KEY").unwrap(),
);

let external_id = "a unique immutable string that represents your user".to_string();
let passkey_display_name =
    "the label for the user's passkey that they will see when logging in".to_string();

let transaction = passage_flex
    .create_register_transaction(external_id, passkey_display_name)
    .await
    .unwrap();

创建身份验证事务

要创建启动用户密钥身份验证的事务,请使用 create_authenticate_transaction 方法。

use passage_flex::PassageFlex;

let passage_flex = PassageFlex::new(
    std::env::var("PASSAGE_APP_ID").unwrap(),
    std::env::var("PASSAGE_API_KEY").unwrap(),
);

let external_id = "a unique immutable string that represents your user".to_string();

let transaction = passage_flex
    .create_authenticate_transaction(external_id)
    .await
    .unwrap();

验证nonce

要验证从密钥注册或身份验证仪式的末尾收到的nonce,请使用 verify_nonce 方法。

use passage_flex::PassageFlex;

let passage_flex = PassageFlex::new(
    std::env::var("PASSAGE_APP_ID").unwrap(),
    std::env::var("PASSAGE_API_KEY").unwrap(),
);

let nonce =
    "a unique single-use value received from the client after a passkey ceremony".to_string();

match passage_flex.verify_nonce(nonce).await {
    Ok(external_id) => {
        // use external_id to do things like generate and send your own auth token
    }
    Err(err) => {
        // nonce was invalid or unable to be verified
    }
}

检索用户信息

要通过外部ID(您提供的唯一、不可变ID,用于将Passage用户与您的用户关联)检索有关用户的信息,请使用 get_user 方法。

use passage_flex::PassageFlex;

let passage_flex = PassageFlex::new(
    std::env::var("PASSAGE_APP_ID").unwrap(),
    std::env::var("PASSAGE_API_KEY").unwrap(),
);

// this is the same value used when creating a transaction
let external_id = your_user.id;

// get user info
let user_info = passage_flex.get_user(external_id).await.unwrap();
println!("{:?}", user_info.webauthn_devices);

检索用户的密钥设备

要检索有关用户密钥设备的信息,请使用 get_devices 方法。

use passage_flex::PassageFlex;

let passage_flex = PassageFlex::new(
    std::env::var("PASSAGE_APP_ID").unwrap(),
    std::env::var("PASSAGE_API_KEY").unwrap(),
);

// this is the same value used when creating a transaction
let external_id = your_user.id;

// get devices
let passkey_devices = passage_flex.get_devices(external_id).await.unwrap();
for device in passkey_devices {
    println!("{}", device.usage_count);
}

撤销用户的密钥设备

要撤销用户的密钥设备,请使用 revoke_device 方法。

use passage_flex::PassageFlex;
use chrono::{Duration, NaiveDate, Utc};

let passage_flex = PassageFlex::new(
    std::env::var("PASSAGE_APP_ID").unwrap(),
    std::env::var("PASSAGE_API_KEY").unwrap(),
);

// this is the same value used when creating a transaction
let external_id = your_user.id;
let last_year = Utc::now().naive_utc().date() - Duration::days(365);

// get devices
let passkey_devices = passage_flex.get_devices(external_id.clone()).await.unwrap();

for device in passkey_devices {
    // revoke old devices that haven't been used in the last year
    let last_login_at_parsed =
        NaiveDate::parse_from_str(&device.last_login_at, "%Y-%m-%dT%H:%M:%S%z").unwrap();

    if last_login_at_parsed < last_year {
        if let Err(err) = passage_flex
            .revoke_device(external_id.clone(), device.id)
            .await
        {
            // device couldn't be revoked
        }
    }
}

依赖项

~4–15MB
~220K SLoC