kilork / openid

OpenID Connect Rust Library
The Unlicense
61 stars 22 forks source link

Way to add query parameter to redirect URL #5

Closed brianhv closed 4 years ago

brianhv commented 4 years ago

Would it make sense (assuming it's not there already and I'm missing it) to add a way to add a query parameter to the callback URL after the Client is constructed? My use case is returning the user to the page they were trying to hit before they were forced to log in.

I imagine this working by adding a field to the Options struct for auth_url(). For example, if the redirect is set to https://example.com/login/oauth2/code/oidc when the Client is constructed:

// This returns a url with a callback of https://example.com/login/oauth2/code/oidc
let auth_url = oidc_client.auth_url(&Options {
    scope: Some("email".into()),
    ..Default::default()
});

// So does this
let auth_url = oidc_client.auth_url(&Options {
    scope: Some("email".into()),
    extra_callback_query: None,
    ..Default::default()
});

// But this returns a url with a callback of
// https://example.com/login/oauth2/code/oidc?original=/return/path/here
let auth_url = oidc_client.auth_url(&Options {
    scope: Some("email".into()),
    extra_callback_query: Some(("original", "/return/path/here")),
    ..Default::default()
});

I'm in no way attached to names or data types here; just illustrating the principle.

brianhv commented 4 years ago

I'm going to rescind this request unless someone else thinks it's a good idea. This library seems to be consistent with others as-is, and I've been able to obtain the behavior I want by storing the redirect in the session.

kilork commented 4 years ago

Hi, I think you need to use state field, for example:

#[get("/oauth2/authorization/oidc")]
async fn authorize(
    oidc_client: web::Data<DiscoveredClient>,
    authorize_query: web::Query<AuthorizeQuery>,
) -> impl Responder {
    let auth_url = oidc_client.auth_url(&Options {
        scope: Some("email".into()),
        state: authorize_query.state.clone(),
        ..Default::default()
    });

    debug!("authorize: {}", auth_url);

    HttpResponse::Found()
        .header(http::header::LOCATION, auth_url.to_string())
        .finish()
}

The whole example is here:

https://github.com/kilork/rustorrent/blob/master/backend/src/login.rs

Some info about state field:

https://auth0.com/docs/protocols/oauth2/oauth-state

brianhv commented 4 years ago

Ah, that's even better! Thanks for pointing that out!