Skip to main content

OAuthConfig

Struct OAuthConfig 

Source
pub struct OAuthConfig {
    pub link_by_verified_email: bool,
    pub state_ttl_secs: u64,
    pub success_redirect: String,
    pub failure_redirect: String,
    pub token_delivery: String,
    pub name_field: String,
    pub avatar_field: String,
    pub providers: BTreeMap<String, OAuthProviderConfig>,
}
Expand description

Signing in with somebody else’s account.

Each [oauth.<provider>] block turns one provider on, and a block needs only the two credentials that provider issued:

[oauth.github]
client_id     = "${GITHUB_CLIENT_ID}"
client_secret = "${GITHUB_CLIENT_SECRET}"

[oauth.google]
client_id     = "${GOOGLE_CLIENT_ID}"
client_secret = "${GOOGLE_CLIENT_SECRET}"

Everything else — the authorize URL, the token URL, where the profile is read from, which scopes ask for an email, whether the provider wants PKCE, whether it insists on the client secret as HTTP Basic — apiplant knows for github, google, linkedin and x. A provider it does not know is configured in full (see OAuthProviderConfig::style), which is how a fifth one is added without waiting for a release.

Turning any of this on mounts <base>/auth/oauth/… and adds the oauth_state resource. With no block at all, none of it exists.

Fields§

§link_by_verified_email: bool

Whether a verified address from a provider may sign somebody in to an existing account carrying the same address (default true).

This is the convenience that makes “I registered with a password, then came back through Google” work, and it is safe only because the address must be one the provider says it verified. An unverified address is never matched, whatever this is set to — that is not a policy, it is the difference between signing in and taking over. Set it false and a matching address is refused with an answer that says how to connect the two deliberately — sign in the way you already can, then link the provider from an authenticated session. Inconvenient, and never wrong.

The same refusal is what an unverified matching address always gets, whatever this is set to.

§state_ttl_secs: u64

How long a started sign-in stays completable, in seconds (default 600). Long enough to read a consent screen, short enough that an abandoned flow is not a lasting hole. Clamped to 60–3600.

§success_redirect: String

Where the browser lands after a successful sign-in through the redirecting endpoint, as a path on this site (default /).

A caller can override it per flow with ?return_to=/somewhere, which is accepted only as a path — never a full URL — because a redirect target somebody else chooses is how a sign-in page becomes a phishing hop.

§failure_redirect: String

Where a failed sign-in lands, as a path. Empty (the default) answers with a plain JSON error instead, which is what you want while setting providers up and not what you want in front of users.

§token_delivery: String

How the session token reaches the browser on the redirecting endpoint:

ValueEffect
fragment (default)…/#token=… — a fragment is never sent to a server, so it stays out of proxy logs and Referer headers
query…?token=… — easier to read from a server-rendered page, and it is in those logs
jsonno redirect at all: the callback answers { "token": …, "user": … }, which is what a single-page app posting the code itself wants
§name_field: String

The user column a provider’s name is written to on sign-in, or empty to write none. display_name is in the built-in model; an app that calls it something else names it here, and one that would rather keep its own copy of a name sets this to "".

§avatar_field: String

The user column a provider’s picture is written to, or empty for none. Same bargain as name_field.

Both are written on every sign-in, not only the first: people change their name and their picture, and a copy that is only ever right on the day the account was created is worse than no copy.

§providers: BTreeMap<String, OAuthProviderConfig>

The providers, keyed by name. Written as [oauth.github] rather than [oauth.providers.github] — the flattening is what buys that, and the cost is that a mistyped setting above becomes a provider nobody asked for, which is refused at boot rather than ignored.

Implementations§

Source§

impl OAuthConfig

Source

pub fn enabled(&self) -> bool

Whether any provider is usable — which is what mounts the routes.

Source

pub fn active_providers(&self) -> Vec<&str>

The names of the providers that are on, in a stable order.

Source

pub fn state_ttl(&self) -> u64

state_ttl_secs, clamped to something a sign-in can actually happen in.

Trait Implementations§

Source§

impl Clone for OAuthConfig

Source§

fn clone(&self) -> OAuthConfig

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for OAuthConfig

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Default for OAuthConfig

Source§

fn default() -> Self

Returns the “default value” for a type. Read more
Source§

impl<'de> Deserialize<'de> for OAuthConfig

Source§

fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>
where __D: Deserializer<'de>,

Deserialize this value from the given Serde deserializer. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> DeserializeOwned for T
where T: for<'de> Deserialize<'de>,

Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more