Flask - 在使用 make_request 重定向之前向客户端发送 JSON 数据
Flask - send JSON data to client before redirecting with make_request
我有这个回调 url 有一个重定向:
@spotify_auth_bp.route("/callback", methods=['GET', 'POST'])
def spotify_callback():
SPOTIFY_TOKEN_URL = "https://accounts.spotify.com/api/token"
CLIENT_ID = os.environ.get('SPOTIPY_CLIENT_ID')
CLIENT_SECRET = os.environ.get('SPOTIPY_CLIENT_SECRET')
REDIRECT_URI = os.environ.get('SPOTIPY_REDIRECT_URI')
auth_token = request.args['code']
code_payload = {
"grant_type": "authorization_code",
"code": auth_token,
"redirect_uri": REDIRECT_URI,
'client_id': CLIENT_ID,
'client_secret': CLIENT_SECRET,
}
post_request = requests.post(SPOTIFY_TOKEN_URL, data=code_payload)
# Auth Step 5: Tokens are Returned to Application
response_data = json.loads(post_request.text)
access_token = response_data["access_token"]
refresh_token = response_data["refresh_token"]
token_type = response_data["token_type"]
expires_in = response_data["expires_in"]
token_info = {'access_token': access_token,
'refresh_token': refresh_token,
'token_type': token_type,
'expires_in': expires_in}
res = make_response(redirect('http://localhost/about', code=302))
# I'd rather send token_info to `localStorage` at my client, instead of setting cookies
#res.set_cookie('access_token', access_token)
#res.set_cookie('refresh_token', refresh_token)
#res.set_cookie('token_type', token_type)
#res.set_cookie('expires_in', str(expires_in))
return res
有没有办法在重定向发生之前通过 make_response()
将上面的 'token_info' 和 jsonify()
(或其他)发送给客户端?
如果您担心 OAuth 流程,请阅读 foot-notes!
根据HTTP 302 Redirect - is a message-body needed?, you can return a body in a 302 Redirect
. Indeed RFC2616不禁止发送响应body。
好吧,我不是 Flask 专家,但这应该可以胜任。它 returns JSON 在 302 Redirect
响应的 body 中。注意你还应该设置正确的Content-Type
header(我的例子中没有)。
import json
from flask import Flask, redirect, Response
app = Flask(__name__)
def jsonResponseFactory(data):
'''Return a callable in top of Response'''
def callable(response=None, *args, **kwargs):
'''Return a response with JSON data from factory context'''
return Response(json.dumps(data), *args, **kwargs)
return callable
@app.route('/')
def hello_world():
token_info = {
'access_token': '...',
'refresh_token': '...',
'token_type': '...',
'expires_in': '...'
}
return redirect(
'http://localhost/about',
302,
jsonResponseFactory(token_info)
)
顺便说一句,如果您的客户端需要读取令牌,它不应该自动跟随 重定向!此外,我不知道 302 Redirect
是否是您的 OAuth 回调端点的最佳答案。但这一切都取决于上下文。
编辑:
以下是评论反馈后的一些笔记。
- 您不应在
localStorage
中存储令牌。 Auth0 website. Furthermore, browsers (starting with Safari) will now drop localStorage after 7 days without user interaction 有很好的解释
- 同样来自 Auth0(我完全同意)应该处理令牌 server-side。
- 我会按原样回答(即使范围不理想),因为它实际上是对您的 HTTP 相关问题的回答。
我有这个回调 url 有一个重定向:
@spotify_auth_bp.route("/callback", methods=['GET', 'POST'])
def spotify_callback():
SPOTIFY_TOKEN_URL = "https://accounts.spotify.com/api/token"
CLIENT_ID = os.environ.get('SPOTIPY_CLIENT_ID')
CLIENT_SECRET = os.environ.get('SPOTIPY_CLIENT_SECRET')
REDIRECT_URI = os.environ.get('SPOTIPY_REDIRECT_URI')
auth_token = request.args['code']
code_payload = {
"grant_type": "authorization_code",
"code": auth_token,
"redirect_uri": REDIRECT_URI,
'client_id': CLIENT_ID,
'client_secret': CLIENT_SECRET,
}
post_request = requests.post(SPOTIFY_TOKEN_URL, data=code_payload)
# Auth Step 5: Tokens are Returned to Application
response_data = json.loads(post_request.text)
access_token = response_data["access_token"]
refresh_token = response_data["refresh_token"]
token_type = response_data["token_type"]
expires_in = response_data["expires_in"]
token_info = {'access_token': access_token,
'refresh_token': refresh_token,
'token_type': token_type,
'expires_in': expires_in}
res = make_response(redirect('http://localhost/about', code=302))
# I'd rather send token_info to `localStorage` at my client, instead of setting cookies
#res.set_cookie('access_token', access_token)
#res.set_cookie('refresh_token', refresh_token)
#res.set_cookie('token_type', token_type)
#res.set_cookie('expires_in', str(expires_in))
return res
有没有办法在重定向发生之前通过 make_response()
将上面的 'token_info' 和 jsonify()
(或其他)发送给客户端?
如果您担心 OAuth 流程,请阅读 foot-notes!
根据HTTP 302 Redirect - is a message-body needed?, you can return a body in a 302 Redirect
. Indeed RFC2616不禁止发送响应body。
好吧,我不是 Flask 专家,但这应该可以胜任。它 returns JSON 在 302 Redirect
响应的 body 中。注意你还应该设置正确的Content-Type
header(我的例子中没有)。
import json
from flask import Flask, redirect, Response
app = Flask(__name__)
def jsonResponseFactory(data):
'''Return a callable in top of Response'''
def callable(response=None, *args, **kwargs):
'''Return a response with JSON data from factory context'''
return Response(json.dumps(data), *args, **kwargs)
return callable
@app.route('/')
def hello_world():
token_info = {
'access_token': '...',
'refresh_token': '...',
'token_type': '...',
'expires_in': '...'
}
return redirect(
'http://localhost/about',
302,
jsonResponseFactory(token_info)
)
顺便说一句,如果您的客户端需要读取令牌,它不应该自动跟随 重定向!此外,我不知道 302 Redirect
是否是您的 OAuth 回调端点的最佳答案。但这一切都取决于上下文。
编辑: 以下是评论反馈后的一些笔记。
- 您不应在
localStorage
中存储令牌。 Auth0 website. Furthermore, browsers (starting with Safari) will now drop localStorage after 7 days without user interaction 有很好的解释
- 同样来自 Auth0(我完全同意)应该处理令牌 server-side。
- 我会按原样回答(即使范围不理想),因为它实际上是对您的 HTTP 相关问题的回答。