Expand description
Provides an implementation of the IndieAuth standard.
The implementations in this crate allows for one to request a Token, verify it and other things.
Requesting A Token
In order to request a token or a profile, one needs to construct an authorization URL that’ll allow the user to provide you with an authorization code. You can build the such by doing the following:
use indieweb::standards::indieauth;
use indieweb::http::ureq::Client as UreqHttpClient;
use indieauth::Client;
use url::Url;
// Get networking client.
let http_client = UreqHttpClient::default();
// Define who I want to be.
let me: Url = "https://jacky.wtf".parse().unwrap();
// Create a simple client for making requests.
let client: indieauth::StockClient = (
indieauth::ClientId::new("https://jacky.wtf".into()),
indieauth::AuthUrl::from_url("https://jacky.wtf/auth/auth".parse().unwrap()),
indieauth::TokenUrl::from_url("https://jacky.wtf/auth/token".parse().unwrap())
).into();
// Build the authorization URL to get an authorization code.
let response = client.dispatch(&http_client,
indieauth::Request::BuildAuthorizationUrl {
me: Some(me.clone()),
scope: None,
redirect_uri: None
});
// Prune out the fields from the request.
let response_opt: Option<(_, _, _, _)> = response.as_ref()
.ok()
.and_then(|r| {
if let indieauth::Response::AuthenticationUrl { url, verifier, challenge,
csrf_token } = r {
Some((url.clone(), challenge.clone(), verifier.clone(), csrf_token.clone()))
.filter(|_| {
url.query_pairs().any(|(key, value)| {
key == "me" && value == me.as_str()
})
})
} else {
None
}
})
.clone();
assert!(
response_opt
.as_ref()
.map(|(url, _, _, _)| url)
.map(|url| {
url.query_pairs().any(|(key, value)| {
key == "me" && value == me.as_str()
})
}).unwrap_or(false),
"confirms the authorization URL to send the user to on behalf of them");
// Direct the user to the location of `response_opt.unwrap().0`.
Redeeming an Authorization Code
The IndieAuth server will do the work of confirming the identity and scopes that the site ends up permitting. You’ll be redirected back to with an authoriz ation code or error information. This step is meant to help capture that kind of information.
Note
- The logic for checking CSRF tokens is up to your implementation. It’s strongly recommended to do to prevent forged requests.
use indieweb::{
standards::indieauth::{self, oauth2, Client, StockClient,
ClientId, AuthUrl, TokenUrl, Request, DesiredResourceAuthorization},
http::ureq::Client as UreqHttpClient
};
let http_client = UreqHttpClient::default();
let client: StockClient = (
ClientId::new("https://jacky.wtf".into()),
AuthUrl::from_url("https://jacky.wtf/auth/auth".parse().unwrap()),
TokenUrl::from_url("https://jacky.wtf/auth/token".parse().unwrap())
).into();
let code = oauth2::AuthorizationCode::new("abcdefghijklmnopqrstuvxwyz123456".to_string());
client.dispatch(&http_client, Request::CompleteAuthorization {
code,
resource: DesiredResourceAuthorization::Profile,
code_verifier: String::default(),
redirect_uri: None
});
The expected response from that dispatch call could be either the providing of a profile or of a token.
Verifying A Token
The act of verification is done by doing the following:
use indieweb::{
standards::indieauth::{self, oauth2, Client, StockClient,
ClientId, AuthUrl, TokenUrl, Request, DesiredResourceAuthorization},
http::ureq::Client as UreqHttpClient
};
use oauth2::AccessToken;
let http_client = UreqHttpClient::default();
let client: StockClient = (
ClientId::new("https://jacky.wtf".into()),
AuthUrl::from_url("https://jacky.wtf/auth/auth".parse().unwrap()),
TokenUrl::from_url("https://jacky.wtf/auth/token".parse().unwrap())
).into();
let token = AccessToken::new("magic-token".to_string());
client.dispatch(&http_client, Request::VerifyAccessToken(token));
What’s missing from this implementation is logic for things like AutoAuth or TicketAuth. This also is locked at the 26 Nov 2020 version.
Re-exports
pub use oauth2;