9个不稳定版本

0.5.0 2024年4月6日
0.4.2 2023年3月22日
0.4.1 2023年1月2日
0.4.0 2022年3月30日
0.1.0-alpha.12019年10月9日

#64 in 认证

Download history 70/week @ 2024-04-29 65/week @ 2024-05-06 63/week @ 2024-05-13 161/week @ 2024-05-20 126/week @ 2024-05-27 84/week @ 2024-06-03 200/week @ 2024-06-10 180/week @ 2024-06-17 138/week @ 2024-06-24 138/week @ 2024-07-01 171/week @ 2024-07-08 172/week @ 2024-07-15 414/week @ 2024-07-22 204/week @ 2024-07-29 235/week @ 2024-08-05 158/week @ 2024-08-12

1,018 每月下载量

MIT/Apache

55KB
619

async-oauth2

github crates.io docs.rs build status

异步OAuth2流程实现,尽可能遵循 RFC 6749


示例

要查看库的使用情况,您可以查看我们的示例之一

如果已经检出项目,可以这样运行

cargo run --manifest-path=examples/Cargo.toml --bin spotify --
    --client-id <client-id> --client-secret <client-secret>
cargo run --manifest-path=examples/Cargo.toml --bin google --
    --client-id <client-id> --client-secret <client-secret>
cargo run --manifest-path=examples/Cargo.toml --bin twitch --
    --client-id <client-id> --client-secret <client-secret>

注意:您需要配置您的客户端集成,允许重定向到 http://localhost:8080/api/auth/redirect 以使其生效。这取决于所使用的集成方式。


授权码授权

这是最常见的OAuth2流程。

use oauth2::*;
use url::Url;

pub struct ReceivedCode {
    pub code: AuthorizationCode,
    pub state: State,
}

let reqwest_client = reqwest::Client::new();

// Create an OAuth2 client by specifying the client ID, client secret,
// authorization URL and token URL.
let mut client = Client::new(
    "client_id",
    Url::parse("http://authorize")?,
    Url::parse("http://token")?
);

client.set_client_secret("client_secret");
// Set the URL the user will be redirected to after the authorization
// process.
client.set_redirect_url(Url::parse("http://redirect")?);
// Set the desired scopes.
client.add_scope("read");
client.add_scope("write");

// Generate the full authorization URL.
let state = State::new_random();
let auth_url = client.authorize_url(&state);

// This is the URL you should redirect the user to, in order to trigger the
// authorization process.
println!("Browse to: {}", auth_url);

// Once the user has been redirected to the redirect URL, you'll have the
// access code. For security reasons, your code should verify that the
// `state` parameter returned by the server matches `state`.
let received: ReceivedCode = listen_for_code(8080).await?;

if received.state != state {
   panic!("CSRF token mismatch :(");
}

// Now you can trade it for an access token.
let token = client.exchange_code(received.code)
    .with_client(&reqwest_client)
    .execute::<StandardToken>()
    .await?;


隐式授权

此流程直接从授权端点获取访问令牌。

在使用此流程之前,请务必理解其安全影响。在大多数情况下,上面的授权码授权流程比隐式授权流程更受欢迎。

use oauth2::*;
use url::Url;

pub struct ReceivedCode {
    pub code: AuthorizationCode,
    pub state: State,
}

let mut client = Client::new(
    "client_id",
    Url::parse("http://authorize")?,
    Url::parse("http://token")?
);

client.set_client_secret("client_secret");

// Generate the full authorization URL.
let state = State::new_random();
let auth_url = client.authorize_url_implicit(&state);

// This is the URL you should redirect the user to, in order to trigger the
// authorization process.
println!("Browse to: {}", auth_url);

// Once the user has been redirected to the redirect URL, you'll have the
// access code. For security reasons, your code should verify that the
// `state` parameter returned by the server matches `state`.
let received: ReceivedCode = get_code().await?;

if received.state != state {
    panic!("CSRF token mismatch :(");
}


资源所有者密码凭据授权

您可以通过调用 Client::exchange_password 方法并包含用户名和密码来请求 密码 访问令牌。

use oauth2::*;
use url::Url;

let reqwest_client = reqwest::Client::new();

let mut client = Client::new(
    "client_id",
    Url::parse("http://authorize")?,
    Url::parse("http://token")?
);

client.set_client_secret("client_secret");
client.add_scope("read");

let token = client
    .exchange_password("user", "pass")
    .with_client(&reqwest_client)
    .execute::<StandardToken>()
    .await?;


客户端凭据授权

您可以通过调用 Client::exchange_client_credentials 方法来请求 客户端凭据 访问令牌。

use oauth2::*;
use url::Url;

let reqwest_client = reqwest::Client::new();
let mut client = Client::new(
    "client_id",
    Url::parse("http://authorize")?,
    Url::parse("http://token")?
);

client.set_client_secret("client_secret");
client.add_scope("read");

let token_result = client.exchange_client_credentials()
    .with_client(&reqwest_client)
    .execute::<StandardToken>();


与oauth2-rs的关系

这是 oauth2-rs 的分支。

主要区别是

  • 从Client中移除不必要的类型参数 (查看讨论)。
  • 仅支持一个客户端实现 (reqwest)。
  • 移除大多数新类型,除了 Scope 和秘密类型,因为它们使API更难使用。

依赖关系

~5–17MB
~246K SLoC