pub struct NativeAuthFlow<S: ConsentScopes> { /* private fields */ }Expand description
Native-app OAuth composition root. See the module docs.
S is the scope tier: it determines what goes on the authorize wire,
what the grant is checked against, and what the yielded token source is
witnessed for — one type parameter across the whole credential story.
Implementations§
Source§impl<S: ConsentScopes> NativeAuthFlow<S>
impl<S: ConsentScopes> NativeAuthFlow<S>
Sourcepub async fn new(config: NativeConfig) -> Result<Self, NativeAuthInitError>
pub async fn new(config: NativeConfig) -> Result<Self, NativeAuthInitError>
Construct a flow, fetching the authorization server’s discovery document once.
No OAuth client is built here — a native client’s redirect URI does not exist until a loopback socket is bound, so the client is assembled per use from the discovered endpoints.
§Errors
NativeAuthInitError::Discovery if the document cannot be fetched
or fails RFC 8414 §3.3 issuer validation.
Sourcepub fn start(&self, redirect_uri: &str) -> Url
pub fn start(&self, redirect_uri: &str) -> Url
Begin an authorization attempt; returns the URL to open in the browser.
redirect_uri is the loopback address the consumer has already
bound, forwarded verbatim to both legs of the flow. Pass it
exactly as the listener reports it — it is never parsed, for the
same byte-identity reason as
NativeConfig::with_resource, and RFC 6749 §4.1.3 requires the
token leg to repeat it unchanged.
Any attempt already pending is discarded: at most one authorization can be in flight, and the newest supersedes it. The abandoned attempt’s state can then never be completed, which is the correct outcome for a flow the user restarted.
Emits no nonce — there is no id_token for one to bind to.
Sourcepub fn token_source<T: TokenStore>(
&self,
store: T,
) -> Result<RefreshTokenSource<AuthClient, T, S>, NativeAuthInitError>
pub fn token_source<T: TokenStore>( &self, store: T, ) -> Result<RefreshTokenSource<AuthClient, T, S>, NativeAuthInitError>
A renewing token source over an already-held refresh token.
This is the restart path: a native app relaunching with a credential
in its keystore has no authorization code to exchange, and needs no
browser round trip. store must already hold the refresh token.
The returned source is witnessed for S on the same terms as
complete’s — the guarantee attaches to use, and
every renewal re-checks the grant. So this constructor needs no proof
from its caller and still cannot yield an unchecked token.
§Errors
NativeAuthInitError::OAuthClient if the HTTP client cannot be
built.
Sourcepub async fn complete<T: TokenStore>(
&self,
callback_query: &str,
store: T,
) -> Result<RefreshTokenSource<AuthClient, T, S>, CallbackError>
pub async fn complete<T: TokenStore>( &self, callback_query: &str, store: T, ) -> Result<RefreshTokenSource<AuthClient, T, S>, CallbackError>
Complete an attempt from the raw redirect query string.
callback_query is everything after the ? in the redirect the
loopback listener received — passed through untouched. This method
parses it, enforces single-use state, exchanges the code with the
stored PKCE verifier, checks the granted scope covers S, persists
the refresh token into store, and returns the renewing source.
§Errors
See CallbackError. Note that
AuthorizationDenied is the
ordinary “user said no” outcome, not a defect.