2 个不稳定版本
0.2.0 | 2024年1月11日 |
---|---|
0.1.0 | 2024年1月6日 |
#186 在 认证
240KB
3K SLoC
远航
非官方的 Firebase Auth REST API 的 Rust 客户端。
安装
请通过 CLI 添加此库
$ cargo add fars
或将依赖项添加到您的 Cargo.toml
[dependencies]
fars = "0.2.0"
功能
本 crate 中的所有功能如下
- 默认
- (可选)
verify
- (可选)
custom_client
支持的 API
以下为 Firebase Auth REST API 的支持 API
- 交换自定义令牌以获取 ID 和刷新令牌
- 使用刷新令牌交换 ID 令牌
- 使用电子邮件/密码注册
- 使用电子邮件/密码登录
- 匿名登录
- 使用 OAuth 凭据登录
- 获取电子邮件提供者
- 发送密码重置电子邮件
- (未测试) 验证密码重置代码
- (未测试) 确认密码重置
- 更改电子邮件
- 更改密码
- 更新个人资料
- 获取用户数据
- 使用电子邮件/密码关联
- 使用 OAuth 凭据关联
- 取消关联提供者
- 发送电子邮件验证
- (未测试) 确认电子邮件验证
- 删除账户
[!注意] 不支持的 API 已实现但未测试。
支持的 OAuth ID 提供商
以下为支持的 OAuth ID 提供商
- (未实现) Apple (
apple..com
) - (未实现) Apple Game Center (
gc..apple..com
) - (未测试) Facebook (
facebook..com
) - (未实现) GitHub (
github..com
) - Google (
google..com
) - (未实现) Google Play Games (
playgames..google..com
) - (未实现) LinkedIn (
linkedin..com
) - (未实现) Microsoft (
microsoft..com
) - (未测试) Twitter (
twitter.com
) - (未实现) Yahoo (
yahoo.com
)
[!NOTE] 不支持的服务提供商可能尚未经过测试,或者
IdpPostBody
的格式在 官方API参考 中未文档化。
API 使用
根据以下步骤提供基于会话(fars::Session
)的语义接口。
[!IMPORTANT]
- ID令牌(
fars::Session.id_token
)有过期日期。- 当ID令牌过期时,通过会话调用API会自动通过刷新令牌API刷新ID令牌。
- 所有通过会话调用的API都会消耗会话并返回一个新的会话,该会话具有相同的ID令牌或刷新后的ID令牌,除了删除账户API。
因此,每次您通过返回的新会话使用会话调用API时,都必须更新会话。
登录用户的用法
- 使用您的Firebase项目API密钥创建一个配置(
fars::Config
)。 - 通过配置使用支持的选择(电子邮件和密码 / OAuth / 匿名 / 存储的刷新令牌)进行登录或注册,然后获取登录用户的会话(
fars::Session
)。 - 通过会话使用Auth API对登录用户进行操作,或使用ID令牌(
fars::Session.id_token
)对其他Firebase API进行操作。
以下是一个使用 电子邮件/密码 注册和用 tokio 和 anyhow 获取用户数据的示例代码
use fars::Config;
use fars::ApiKey;
use fars::Email;
use fars::Password;
#[tokio::main]
async fn main() -> anyhow::Result<()> {
// 1. Create a config with your Firebase project API key.
let config = Config::new(
ApiKey::new("your-firebase-project-api-key"),
);
// 2. Sign up with email and password then get a session.
let session = config.sign_up_with_email_password(
Email::new("[email protected]"),
Password::new("password"),
).await?;
// 3. Get user data through the session and get a new session.
let (new_session, user_data) = session.get_user_data().await?;
// 4. Do something with new_session and user_data.
Ok(())
}
未登录用户的用法
- 使用您的Firebase项目API密钥创建一个配置(
fars::Config
)。 - 通过配置使用Auth API对未登录用户进行操作。
以下是一个使用 发送密码重置电子邮件 的示例代码,使用 tokio 和 anyhow
use fars::Config;
use fars::ApiKey;
use fars::Email;
#[tokio::main]
async fn main() -> anyhow::Result<()> {
// 1. Create a config with your Firebase project API key.
let config = Config::new(
ApiKey::new("your-firebase-project-api-key"),
);
// 2. Send reset password email to specified email through the config if it has been registered.
config.send_reset_password_email(
Email::new("user@example"),
None, // Option: Locale
).await?;
Ok(())
}
使用OAuth凭据登录
[!IMPORTANT] 此crate不提供获取每个ID提供者的OAuth凭据的方法。
当您使用OAuth凭据进行登录时,请实现一种获取目标OAuth凭据的方法。
请参阅支持的OAuth提供者。
Google OAuth
要使用Google OAuth凭据进行登录,
- 使用您的Firebase项目API密钥创建一个配置(
fars::Config
)。 - 从Google OAuth API获取OpenID令牌。请参阅参考。
- 指定
request_uri
和IdpPostBody::Google
进行登录。
以下是一个使用 Google OAuth凭据登录 的示例代码,使用 tokio 和 anyhow
use fars::Config;
use fars::ApiKey;
use fars::OAuthRequestUri;
use fars::IdpPostBody;
#[tokio::main]
async fn main() -> anyhow::Result<()> {
// 1. Create a config with your Firebase project API key.
let config = Config::new(
ApiKey::new("your-firebase-project-api-key"),
);
// 2. Get an OpenID token from Google OAuth by any method.
let google_id_token = "google-open-id-token".to_string();
// 3. Get a session by signing in with Google OAuth credential.
let session = config
.sign_in_with_oauth_credential(
OAuthRequestUri::new("https://your-app.com/redirect/path/auth/handler"),
IdpPostBody::Google {
id_token: google_id_token,
},
)
.await?;
// 4. Do something with the session.
Ok(())
}
错误处理
如果您在此crate中处理错误,请处理 fars::Result
和 fars::Error
。
[!注意]
fars::Error::ApiError
根据 API 参考文档 中的通用错误代码具有一个错误码(fars::error::CommonErrorCode
)。您可以通过匹配错误码(fars::error::CommonErrorCode
)来指定 Firebase Auth 的 API 错误类型。
以下是一个使用 reqwest、tokio 和 anyhow 处理通过电子邮件/密码 登录 的示例代码:
use fars::Config;
use fars::ApiKey;
use fars::Email;
use fars::Password;
#[tokio::main]
async fn main() -> anyhow::Result<()> {
// Create a config.
let config = Config::new(
ApiKey::new("your-firebase-project-api-key"),
);
// Create a session by signing in with email and password.
match config
.sign_in_with_email_password(
Email::new("user@example"),
Password::new("password"),
)
.await
{
// Success
| Ok(session) => {
println!(
"Succeeded to sign in with email/password: {:?}",
session
);
// Do something with the session.
Ok(())
},
// Failure
| Err(error) => {
match error {
// Handle HTTP request error.
| fars::Error::HttpRequestError(error) => {
// Do something with HTTP request error, e.g. retry.
Err(error.into())
},
// Handle API error.
| fars::Error::ApiError {
status_code,
error_code,
response,
} => {
match error_code {
| CommonErrorCode::InvalidLoginCredentials => {
// Do something with invalid login credentials, e.g. display error message for user: "Invalid email or/and password.".
Err(fars::Error::ApiError {
status_code,
error_code,
response,
}
.into())
},
| CommonErrorCode::UserDisabled => {
// Do something with disabled user, e.g. display error message for user: "This user is disabled by administrator, please use another account.".
Err(fars::Error::ApiError {
status_code,
error_code,
response,
}
.into())
},
| CommonErrorCode::TooManyAttemptsTryLater => {
// Do something with too many attempts, e.g. display error message for user: "Too may requests, please try again later.".
Err(fars::Error::ApiError {
status_code,
error_code,
response,
}
.into())
},
| _ => {
// Do something with other API errors.
Err(fars::Error::ApiError {
status_code,
error_code,
response,
}
.into())
},
}
},
// Handle internal errors
| _ => {
// Do something with internal errors.
Err(error.into())
},
}
},
}
}
原始 API 接口
提供 fars::api
模块支持的原始 API。
以下是一个使用 reqwest、tokio 和 anyhow 通过电子邮件/密码 登录 的示例代码:
use fars::ApiKey;
use fars::Client;
use fars::api;
#[tokio::main]
async fn main() -> anyhow::Result<()> {
// 1. Specify your API key.
let api_key = ApiKey::new("your-firebase-project-api-key");
// 2. Create a HTTP client.
let client = Client::new();
// 3. Create a request payload for the sign in API.
let request_payload = api::SignInWithEmailPasswordRequestBodyPayload::new(
"[email protected]".to_string(),
"password".to_string(),
);
// 4. Send a request and receive a response payload of the sign in API.
let response_payload = api::sign_in_with_email_password(
&client,
&api_key,
request_payload,
).await?;
// 5. Do something with the response payload.
Ok(())
}
(可选) ID 令牌验证
通过 fars::verification
模块提供 Firebase Auth 的 ID 令牌验证。
[!注意] ID 令牌验证是一个可选功能。
请通过 CLI 激活此功能
$ cargo add fars --features verify
或在您的
Cargo.toml
中添加功能[dependencies] fars = { version = "0.2.0", features = ["verify"] }
以下是一个使用 tokio 和 anyhow 验证 ID 令牌 的示例代码:
use fars::VerificationConfig;
use fars::ProjectId;
use fars::IdToken;
#[tokio::main]
async fn main() -> anyhow::Result<()> {
// Create a cofig for verification with your Firebase project ID.
let cofing = let config = VerificationConfig::new(
ProjectId::new("firebase-project-id"),
);
// Get an ID token of the Firebase Auth by any method.
let id_token = IdToken::new("id-token");
// Verrify the ID token.
match config.verify_id_token(&id_token).await {
Ok(claims) => {
// Verification succeeded.
},
Err(error) => {
// Verification failed.
},
}
Ok(())
}
HTTP 客户端自定义
提供 Firebase Auth API 的 HTTP 客户端定制接口。
[!注意] HTTP 客户端定制是一个可选功能。
请通过 CLI 激活此功能
$ cargo add fars --features custom_client
或在您的
Cargo.toml
中添加功能[dependencies] fars = { version = "0.2.0", features = ["custom_client"] }
以下是一个使用 tokio 和 anyhow 定制 HTTP 客户端超时选项的示例:
use std::time::Duration;
use fars::Client;
use fars::ApiKey;
use fars::Config;
#[tokio::main]
async fn main() -> anyhow::Result<()> {
// 1. Create a custom client with re-exported `reqwest` client.
let client = fars::reqwest::ClientBuilder::new()
.timeout(Duration::from_secs(60))
.connect_timeout(Duration::from_secs(10))
.build()?;
// 2. Customize HTTP client.
let client = Client::custom(client);
// 3. Create a cofig with customized client.
let config = Config::custom(
ApiKey::new("your-firebase-project-api-key"),
client,
);
// 4. Do something with a customized config.
Ok(())
}
其他示例
请参考 /examples 目录、shell 脚本 以及使用 dioxus 的 Web 前端认证研究。
变更日志
见 CHANGELOG。
许可证
根据您的选择,许可协议为 Apache License, Version 2.0 或 MIT 许可证。
依赖项
~3–19MB
~274K SLoC