Fetching API tokens does not work with requests-oauthlib (but without)

42 Views Asked by At

I try to get a token from an API using requests-oauthlib. This is the essential part of my code:

from flask import Flask, request, redirect
from requests_oauthlib import OAuth2Session

# setting constants …

app = Flask(__name__)
app.config["SECRET_KEY"] = SECRET_KEY


@app.route("/login/")
def login():

    api_session = OAuth2Session(
        API_CLIENT_ID, redirect_uri=API_REDIRECT_URI
    )
    authorization_url, state = api_session.authorization_url(
        API_AUTHORIZATION_BASE_URL
    )

    session["oauth_state"] = state
    return redirect(authorization_url)


@app.route("/callback/")
def callback():
    api_session = OAuth2Session(API_CLIENT_ID, state=session["oauth_state"])

    token = api_session.fetch_token(
        API_TOKEN_URL,
        client_secret=API_CLIENT_SECRET,
        authorization_response=request.url,
        include_client_id=True,
        code=request.args.get("code"),
    )

    return "Tokens received."

When I open the login URL in my browser, I get redirected to the API_AUTHORIZATION_BASE_URL which redirects back to my API_REDIRECT_URI (callback). Then oauthlib.oauth2.rfc6749.errors.AccessDeniedError: (access_denied) raises.

When I try to do the same without requests-oauthlib, just with hand made requests, it works perfectly and I get the token:

import requests

from flask import Flask, request, redirect

# setting constants …

app = Flask(__name__)
app.config["SECRET_KEY"] = SECRET_KEY


@app.route("/login/")
def login():

    return redirect(
        f"{API_AUTHORIZATION_BASE_URL}?client_id={API_CLIENT_ID}&redirect_uri={API_REDIRECT_URI}&response_type=code"
    )


@app.route("/callback/")
def callback():
    data = {
        "client_secret": API_CLIENT_SECRET,
        "grant_type": "authorization_code",
        "code": request.args.get("code"),
        "client_id": API_CLIENT_ID,
        "redirect_uri": API_REDIRECT_URI,
    }

    response = requests.post(API_TOKEN_URL, data=data)

    return "Tokens received."

Even though I tried hard (and learned a lot about the OAuth2 protocoll and requests-oauthlib), I still did not find what's wrong with the requests-oauthlib approach.

Does anybody have a hint for me? This would be great.

1

There are 1 best solutions below

0
Ralf Zosel On

Now, I found the solution by myself: the redirect_uri was missing for OAuth2Session in the callback-function. I had to add it as a further parameter:

@app.route("/callback/")
def callback():
    api_session = OAuth2Session(API_CLIENT_ID, state=session["oauth_state"], redirect_uri=API_REDIRECT_URI,)

With that, it works. :-)