pythonauthlib

authlib.integrations.base_client.errors.MismatchingStateError


Trying to get a token for tradestation with flask_client.

baseurl='https://sim-api.tradestation.com/v2'

oauth.register(
    name='tradestation',
    client_id=api_key,
    client_secret=api_secret,
    access_token_url=baseurl+'/security/authorize',
    access_token_params={ 'grant_type': 'authorization_code' },
    authorize_url=baseurl+'/authorize',
    authorize_params=None,
    api_base_url=baseurl,
    client_kwargs={
        'scope': 'marketdata', # ,trade — for later
        'response_type': 'code',
        'token_endpoint_auth_method': 'client_secret_post',
    },
)

@app.route('/authorize')
def authorize():
    print(flask.request.args.get('state'), flask.session.get('_tradestation_authlib_state_'))
    token = oauth.tradestation.authorize_access_token()

Login part works fine, I'm being redirected to the tradestation login page, after entering credentials I'm being redirected to localhost. In the flask output I see:

GET /authorize?code=<long_code> HTTP/1.1

And it returns this exception for authorize_access_token(). Debug print indeed says that the state is None. By looking into the code I see that it wants to get state from the url, and it's missing:

None c3GjcENWIe7Qg3FdQNYn1iSCuU1jZC

Am I registering the parameters wrongly here? Haven't yet got to the token_endpoint_auth_method, and I cannot find anything wrong with the other parameters.


Solution

  • Doing it the hackish way got me the token in the end:)

    state=flask.session.get('_tradestation_authlib_state_')
    flask.request.args=ImmutableMultiDict({**flask.request.args, 'state': state})
    

    So someone suffering from the same check can use this quick and dirty approach to have it running, still maybe authlib developers may show up with some better solution.