我尝试使用
requests-oauthlib
从 API 获取令牌。这是我的代码的重要部分:
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."
当我在浏览器中打开登录 URL 时,我会被重定向到
API_AUTHORIZATION_BASE_URL
,然后又重定向回我的 API_REDIRECT_URI
(回调)。然后 oauthlib.oauth2.rfc6749.errors.AccessDeniedError: (access_denied)
加注。
当我尝试做同样的没有
requests-oauthlib
时,只需手工提出请求,它就完美地工作并且我得到了令牌:
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."
尽管我努力尝试(并且了解了很多有关 OAuth2 协议和 requests-oauthlib 的知识),但我仍然没有发现 requests-oauthlib 方法有什么问题。
有人给我提示吗?这太好了。
现在,我自己找到了解决方案:回调函数中OAuth2Session缺少redirect_uri。我必须将其添加为进一步的参数:
@app.route("/callback/")
def callback():
api_session = OAuth2Session(API_CLIENT_ID, state=session["oauth_state"], redirect_uri=API_REDIRECT_URI,)
有了这个,它就起作用了。 :-)