oauth2-rs icon indicating copy to clipboard operation
oauth2-rs copied to clipboard

Question about token exchange

Open Luca-spopo opened this issue 4 years ago • 1 comments

I am building an authorization code flow, where my rust server receives an authorization code and I need to exchange it for an access code from the oauth server (facebook in this case)

Facebook docs mention the authorization code, client id and secret need to be sent as part of the query (Google OAuth also seems to expect them in the query)

GET https://graph.facebook.com/v11.0/oauth/access_token?
   client_id={app-id}
   &redirect_uri={redirect-uri}
   &client_secret={app-secret}
   &code={code-parameter}

However, when I am using the exchange_code method in this library, it is populating these parameters in the request body and not the query. Digging into the code, it is populating it in the request body via match on AuthType. The only options seem to be populating the params in the request body or in the auth header. That doesn't seem right so I suspect I am misunderstanding the API. https://docs.rs/oauth2/4.1.0/oauth2/enum.AuthType.html

Here's my code

lazy_static! {
    static ref OAUTH2_CLIENT: oauth2::basic::BasicClient = BasicOAuth2Client::new(oauth2::ClientId::new(CLIENT_ID.to_string()),
    Some(oauth2::ClientSecret::new(CLIENT_SECRET.to_string())),
    oauth2::AuthUrl::new(AUTH_URL.to_string()).unwrap(),
    oauth2::TokenUrl::new(TOKEN_URL.to_string()).ok())
    .set_introspection_uri(oauth2::IntrospectionUrl::new(INTROSPECTION_URL.to_string()).unwrap());
}

    fn get_access_token<'a>(authorization_code: AuthorizationCode<Self>) -> BoxPinDynFuture<'a, Result<Token<Self>, OAuthError>> {
        Box::pin(async move {
            OAUTH2_CLIENT
            .exchange_code(oauth2::AuthorizationCode::new(authorization_code.0))
            .request_async(oauth2::reqwest::async_http_client)
            .await //This gives an Err result
            .map(|token_response| Token::new(token_response.access_token().to_owned()) )
            .map_err(|err| err.into())
        })
    }

Am I using the library incorrectly, or am I misunderstanding something?

Luca-spopo avatar Jul 25 '21 12:07 Luca-spopo

hmm... I'm not quite sure what protocol Facebook is aiming to implement here, but it's not RFC 6749-compliant OAuth2, which specifically states:

The client MUST use the HTTP "POST" method when making access token requests.

Re:

(Google OAuth also seems to expect them in the query)

I don't think that's the case. This crate includes a Google example, which follows the normal OAuth2 flow (GET-based authorization request in the browser followed by POST-based token request in the backend).

ramosbugs avatar Jul 25 '21 21:07 ramosbugs