authlib.integrations.base_client.errors.MismatchingStateError

authlib.integrations.base_client.errors.MismatchingStateError

正在尝试使用 flask_client 获取 tradestation 的令牌。

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()

登录部分工作正常,我被重定向到交易站登录页面,输入凭据后我被重定向到本地主机。在烧瓶输出中我看到:

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

returns authorize_access_token() 的异常。调试打印确实说状态是None。通过查看代码,我发现它想从 url 获取状态,但它丢失了:

None c3GjcENWIe7Qg3FdQNYn1iSCuU1jZC

我这里的参数是不是填错了?还没有达到 token_endpoint_auth_method,我找不到其他参数有什么问题。

最后我以骇人听闻的方式获得了令牌:)

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

所以遭受相同检查的人可以使用这种快速而肮脏的方法来获得它运行,也许 authlib 开发人员可能会出现一些更好的解决方案。