3 个版本
0.0.3 | 2024 年 5 月 2 日 |
---|---|
0.0.2 | 2024 年 4 月 30 日 |
0.0.1 | 2024 年 4 月 24 日 |
#2798 in 魔法豆
每月 36 次下载
用于 siws-recap
27KB
482 行
SIWS - Solana Rust 登录库
一个简单的 Rust 实现,遵循 CAIP-122 (登录 With X) 用于 Solana,遵循 Solana 钱包标准 和 Phantom 钱包的登录 With Solana 协议。
安装
通过在你的项目 Cargo.toml
中将 siws
crate 作为依赖项包含,可以轻松安装 SIWS。
[dependencies]
# ...other dependencies
siws = "0.0.1"
# ...other dependencies
使用方法
SIWS 暴露了两个主要结构体 - SiwsMessage
用于消息验证,和 SiwsOutput
用于登录验证。
SiwsMessage
与 Solana 钱包标准的 SolanaSignInInput
类似,而 SiwsOutput
与 SolanaSignInOutput
类似。
使用这些,你可以验证登录请求,并验证登录消息。
你主要会想要使用 SiwsOutput
结构体,因为其主要目的是为你提供简单的验证其签名的方法。
但是,如果你希望验证 SIWS 消息(你应该这样做),你可以使用 SiwsMessage::try_from
从 SiwsOutput
的 signed_message
字段中提取它。
端到端示例
以下示例代码展示了使用 actix-web
、time
和 siws
的完整 Rust 程序,用于接收包含 SIWS 输出的 JSON 对象,从中创建 SIWS 消息,验证签名并验证消息。
Cargo.toml
:
[package]
name = "siws-server-example"
version = "0.1.0"
edition = "2021"
[dependencies]
actix-web = "4.5.1"
siws = { path = "../../siws-rs" }
time = "0.3.36"
src/main.rs
use actix_web::{error, web, App, HttpServer, Result};
use siws::message::{SiwsMessage, ValidateOptions};
use siws::output::SiwsOutput;
use time::OffsetDateTime;
async fn validate_and_verify(output: web::Json<SiwsOutput>) -> Result<String> {
// Read the message from output.signed_message
let message = SiwsMessage::try_from(&output.signed_message).map_err(error::ErrorBadRequest)?;
// Validate the message
message
.validate(ValidateOptions {
domain: Some("www.exmaple.com".into()), // Ensure domain is www.example.com
nonce: Some("1337nonce".into()), // Ensure nonce is 1337nonce
time: Some(OffsetDateTime::now_utc()) // Validate IAT, EXP, and NBF according to current time
})
.map_err(error::ErrorBadRequest)?;
output.verify().map_err(error::ErrorBadRequest)?;
Ok(String::from("Successfully verified!"))
}
#[actix_web::main]
async fn main() -> std::io::Result<()> {
HttpServer::new(|| App::new().route("/", web::post().to(validate_and_verify)))
.bind(("127.0.0.1", 8080))?
.run()
.await
}
SIWS 输出
继承了 serde
的 Serialize
和 Deserialize
特性,并且自动将其所有字段重命名为 camelCase
以简化 Solana 钱包支持。
使用 SIWS 输出验证登录
每当您有 SIWS 输出时,只需调用其 verify
方法即可验证其签名。您可以通过解析 JSON 字符串来构建 SIWS 输出。
有关详细信息,请参阅 tests/integration_tests.rs
。
fn verify_from_json_message() -> Result<(), VerifyError> {
let json = include_str!("test_message.json");
let output: SiwsOutput = serde_json::from_str(json).unwrap();
output.verify()?; // Result<(), VerifyError>
Ok(())
}
验证 SIWS 消息
从前面的示例中,如果您想同时验证 SIWS 消息与特定域、nonce 或时间,可以执行以下操作
let message = SiwsMessage::try_from(&output.signed_message).map_err(error::ErrorBadRequest)?;
message.validate(ValidateOptions {
...
})?; // Result<(), ValidateError>
SIWS 消息
SiwsMessage
结构体用于将 SIWS 消息序列化和反序列化为其 ABNF 形式。还实现了额外的方法来支持从 &Vec<u8>
和 &[u8]
解析它,因为 Solana 钱包签名的消息通常作为 UTF-8 字节序列。
从字符串解析 SIWS 消息
您可以从任何符合其 指定 ABNF 的字符串解析 SIWS 消息
fn example_from_str() -> Result<(), ParseError> {
let msg = SiwsMessage::from_str(
"\
www.example.com wants you to sign in with your Solana account:\n\
BSmWDgE9ex6dZYbiTsJGcwMEgFp8q4aWh92hdErQPeVW\n\
\n\
This is some test statement\n\
\n\
URI: test_uri\n\
Version: 1\n\
Chain ID: mainnet\n\
Nonce: abcdefgh\n\
Issued At: 2024-04-24T17:19:02.991469647Z\n\
Expiration Time: 2024-04-24T23:19:02.991482123Z\n\
Not Before: 2024-04-24T18:19:02.99148447Z\n\
Request ID: test_rid\n\
Resources:\n\
- https://www.example.com/test_one\n\
- https://www.example.com/test_two\
",
)?;
// Do something with the message
Ok(())
}
根据 ABNF 序列化 SIWS 消息
您可以通过使用 String::from
获取符合 ABNF 的 SIWS 消息字符串
let siws_message = SiwsMessage {
domain: "www.exmaple.com".into(),
address: "someaddress".into(),
..Default::default()
};
let message_string = String::from(&siws_message);
print!("{}", message_string);
贡献
此项目旨在为 Rust 开发者提供 Sign in With Solana 的基本功能。因此,它旨在保持小巧和管理。
鼓励为此存储库做出贡献。
如果您发现任何错误,请尝试克隆存储库并自行修复,然后提交包含您建议的修复的 PR。
该项目也欢迎新功能,但是功能请求应在之前通过问题进行讨论,以符合项目的极简主义性质。
安全性
此库尚未经过安全审计。
如果您或您认识的人想要审计 siws-rs
,请直接联系作者。
依赖关系
~5.5MB
~103K SLoC