huskarl 0.9.0

A modern OAuth2 client library.
# Refresh token grant

[`RefreshGrant`](crate::grant::refresh::RefreshGrant) (RFC 6749 ยง6) is used to
obtain a new access token using a previously issued refresh token, without
requiring the user to re-authenticate.

## 1. Set up your HTTP client and client authentication

See [Setting up an HTTP client and client
authentication](crate::_docs::guide::setup) for the shared setup the rest of
this page assumes. When constructing a refresh grant directly (steps 2b/2c),
provide client authentication. A grant built via `to_refresh_grant` inherits it
from the parent grant.

## 2a. Create a refresh grant from an existing grant (most common)

The most common way to create a refresh grant is from another grant that has
already been configured. This inherits the same client authentication, `DPoP`,
and HTTP client settings without needing to repeat them.

```rust
use huskarl::{
    grant::{client_credentials::ClientCredentialsGrant, refresh::RefreshGrant},
    prelude::*,
};
# fn example(grant: &ClientCredentialsGrant) {
let refresh_grant: RefreshGrant = grant.to_refresh_grant();
# }
```

## 2b. Set up the grant directly with authorization server metadata

```rust
use huskarl::{
    core::{
        client_auth::ClientSecret,
        secrets::{EnvVarSecret, encodings::StringEncoding},
        server_metadata::AuthorizationServerMetadata,
    },
    grant::refresh::RefreshGrant,
};
# async fn setup_grant() -> Result<(), Box<dyn std::error::Error>> {
# let client = huskarl_reqwest::ReqwestClient::builder()
#     .build()
#     .await?;
#
# let env_secret = EnvVarSecret::new("CLIENT_SECRET", &StringEncoding)?;
# let client_auth: ClientSecret = ClientSecret::new(env_secret);

let metadata = AuthorizationServerMetadata::fetch()
    .http_client(&client)
    .issuer("https://my-issuer")
    .call()
    .await?;

let refresh_grant: RefreshGrant = RefreshGrant::builder_from_metadata(&metadata)
    .client_id("client_id")
    .http_client(client)
    .client_auth(client_auth)
    .build();
# Ok(())
# }
```

## 2c. Alternative: Set up the grant without metadata

```rust
use huskarl::{
    core::{
        client_auth::ClientSecret,
        secrets::{EnvVarSecret, encodings::StringEncoding},
    },
    grant::refresh::RefreshGrant,
};
# async fn setup_grant() -> Result<(), Box<dyn std::error::Error>> {
# let client = huskarl_reqwest::ReqwestClient::builder()
#     .build()
#     .await?;
#
# let env_secret = EnvVarSecret::new("CLIENT_SECRET", &StringEncoding)?;
# let client_auth: ClientSecret = ClientSecret::new(env_secret);

let refresh_grant: RefreshGrant = RefreshGrant::builder()
    .token_endpoint("https://my-server/token".parse()?)
    .client_id("client_id")
    .http_client(client)
    .client_auth(client_auth)
    .build();
# Ok(())
# }
```

## 3. Exchange the refresh token for a new access token

```rust
use huskarl::{
    grant::refresh::{RefreshGrant, RefreshGrantParameters},
    prelude::*,
    token::{AccessToken, RefreshToken},
};
# async fn exchange(
#     refresh_grant: &RefreshGrant,
#     refresh_token: RefreshToken,
# ) -> Result<(), Box<dyn std::error::Error>> {

let params = RefreshGrantParameters::refresh_token(refresh_token);
let response = refresh_grant.exchange(params).await?;
let token: &AccessToken = response.access_token();
# Ok(())
# }
```