在 Flask 会话中存储 oAuth 状态令牌
Posted
技术标签:
【中文标题】在 Flask 会话中存储 oAuth 状态令牌【英文标题】:Storing oAuth state token in Flask session 【发布时间】:2018-02-05 06:21:31 【问题描述】:一些关于 oAuth 的教程使用 Flask 会话在 Flask 会话中存储状态参数和访问令牌。 (Brendan McCollam's very useful presentation from Pycon is an example)
我了解 Flask 将会话存储在客户端的 cookie 中,并且它们很容易暴露(see Michael Grinberg's how-secure-is-the-flask-user-session)。我自己尝试过,并且能够看到令牌过期等。
在烧瓶会话中存储状态和令牌是否正确,或者它们应该存储在其他地方?
代码示例:
@app.route('/login', methods=['GET'])
def login():
provider = OAuth2Session(
client_id=CONFIG['client_id'],
scope=CONFIG['scope'],
redirect_uri=CONFIG['redirect_uri'])
url, state = provider.authorization_url(CONFIG['auth_url'])
session['oauth2_state'] = state
return redirect(url)
@app.route('/callback', methods=['GET'])
def callback():
provider = OAuth2Session(CONFIG['client_id'],
redirect_uri=CONFIG['redirect_uri'],
state=session['oauth2_state'])
token_response = provider.fetch_token(
token_url=CONFIG['token_url'],
client_secret=CONFIG['client_secret'],
authorization_response=request.url)
session['access_token'] = token_response['access_token']
session['access_token_expires'] = token_response['expires_at']
transfers = provider.get('https://transfer.api.globusonline.org/v0.10/task_list?limit=1')
return redirect(url_for('index'))
@app.route('/')
def index():
if 'access_token' not in session:
return redirect(url_for('login'))
transfers = requests.get('https://transfer.api.globusonline.org/v0.10/task_list?limit=1',
headers='Authorization': 'Bearer ' + session['access_token'])
return render_template('index.html.jinja2',
transfers=transfers.json())
【问题讨论】:
有人吗?任何人?我会回答一半......当然我不是唯一一个认为这很重要的人 【参考方案1】:我认为有些教程为了显示更简单的代码而过度简化了。一个好的经验法则是仅将会话 cookie 用于您的应用程序和用户浏览器必须知道的信息,而不是私人信息。这通常会转化为会话 ID 和可能的其他非敏感信息,例如语言选择。
应用该经验法则,我建议在每个标记旁边使用:
授权令牌:根据定义,用户和应用程序都知道此数据,因此在 cookie 中公开它不应该是安全问题。但是,一旦您获得访问代码,确实没有必要保留此令牌,因此我建议您不要将其保存在本地或您的 cookie 中。
访问代码:此数据必须被视为机密,并且只能由您的应用程序和提供商知道。没有理由让任何其他方(包括用户)知道它,因此它不应包含在 cookie 中。如果您需要存储它,请将其本地保存在您的服务器中(可能在您的数据库中,引用您的用户会话 ID)。
CSRF 状态令牌:此数据理想地包含在隐藏表单字段中,并针对服务器端变量进行验证,因此 cookie 似乎是不必要的复杂化。但我不会担心这些数据在 cookie 中,因为它无论如何都是响应的一部分。
请记住,还有诸如烧瓶会话之类的扩展,实际上相同的代码使用服务器端变量而不是 cookie 变量。
【讨论】:
谢谢JavoSN...我一直在寻找这个答案很长一段时间...非常感谢全面的解释。以上是关于在 Flask 会话中存储 oAuth 状态令牌的主要内容,如果未能解决你的问题,请参考以下文章