Authlib 客户端错误:请求和响应中的状态不相等

Mik*_*kin 4 flask authlib

我正在尝试实现authlib客户端和服务器。我以 OAuth2.0 示例为例,并按照教程在 Flask 站点上进行了我自己的客户端授权。这是我的代码:

from flask import Flask, redirect, url_for, session, request

from authlib.flask.client import OAuth
from authlib.client.errors import OAuthException

APP_ID = 'KBtRDO3r2HETjw4TcLznthoj'
APP_SECRET = '3g4C6nbJcTIYX3jyCIEmf6KE8h8pzxUhjy6ArlY3AEgj1snv'

app = Flask('testa_client')
app.debug = True
app.secret_key = 'development'

oauth = OAuth()
oauth.init_app(app)

remote = oauth.register(
    'testa',
    client_id=APP_ID,
    client_secret=APP_SECRET,
    # request_token_params={'scope': 'base'},
    base_url='http://127.0.0.1:5000',
    access_token_url='http://127.0.0.1:5000/auth/token',
    authorize_url='http://127.0.0.1:5000/auth/connect'
)


@app.route('/')
def index():
    return redirect(url_for('login'))


@app.route('/login')
def login():
    callback = url_for(
        'websa_authorized',
        next=request.args.get('next') or request.referrer or None,
        _external=True
    )
    return remote.authorize_redirect(callback=callback)


@app.route('/login/authorized')
def websa_authorized():
    resp = remote.authorize_access_token()
    if resp is None:
        return 'Access denied: reason=%s error=%s' % (
            request.args['error_reason'],
            request.args['error_description']
        )
    if isinstance(resp, OAuthException):
        return 'Access denied: %s' % resp.message

    session['oauth_token'] = (resp['access_token'], '')
    me = remote.get('/user/me')
    return 'Logged in as id=%s name=%s redirect=%s' % \
        (me.data['id'], me.data['name'], request.args.get('next'))


app.run(port=9001)
Run Code Online (Sandbox Code Playgroud)

我所说的服务器代码与https://github.com/authlib/example-oauth2-server存储库中的几乎相同。

当我尝试进行授权时,我会进入授权服务器(在端口 5000 上)并确认我允许访问。但是当我重定向回页面http://127.0.0.1:9001/login/authorized?code=...&state=...上的客户端站点时(在 9001 上),我收到错误消息:

from flask import Flask, redirect, url_for, session, request

from authlib.flask.client import OAuth
from authlib.client.errors import OAuthException

APP_ID = 'KBtRDO3r2HETjw4TcLznthoj'
APP_SECRET = '3g4C6nbJcTIYX3jyCIEmf6KE8h8pzxUhjy6ArlY3AEgj1snv'

app = Flask('testa_client')
app.debug = True
app.secret_key = 'development'

oauth = OAuth()
oauth.init_app(app)

remote = oauth.register(
    'testa',
    client_id=APP_ID,
    client_secret=APP_SECRET,
    # request_token_params={'scope': 'base'},
    base_url='http://127.0.0.1:5000',
    access_token_url='http://127.0.0.1:5000/auth/token',
    authorize_url='http://127.0.0.1:5000/auth/connect'
)


@app.route('/')
def index():
    return redirect(url_for('login'))


@app.route('/login')
def login():
    callback = url_for(
        'websa_authorized',
        next=request.args.get('next') or request.referrer or None,
        _external=True
    )
    return remote.authorize_redirect(callback=callback)


@app.route('/login/authorized')
def websa_authorized():
    resp = remote.authorize_access_token()
    if resp is None:
        return 'Access denied: reason=%s error=%s' % (
            request.args['error_reason'],
            request.args['error_description']
        )
    if isinstance(resp, OAuthException):
        return 'Access denied: %s' % resp.message

    session['oauth_token'] = (resp['access_token'], '')
    me = remote.get('/user/me')
    return 'Logged in as id=%s name=%s redirect=%s' % \
        (me.data['id'], me.data['name'], request.args.get('next'))


app.run(port=9001)
Run Code Online (Sandbox Code Playgroud)

有什么问题?两部分都使用 Authlib 0.8。

Mik*_*kin 9

我花了很多时间在我的代码中找到错误。问题不在于代码,而在于我使用它的方式。我通过本地 IP 地址127.0.0.1和不同的端口访问了这两个应用程序。浏览器为此类相关 URI 混合会话和 cookie。我http://test:9001为该服务提供了另一个本地域名(就我而言),这解决了我的问题。

当您使用 OAuth 时,不要使用本地地址和相同的域。

  • 或者服务器和客户端有不同的 SESSION_NAME,那也可以。 (3认同)