在 Flask 会话中存储 oAuth 状态令牌 [英] Storing oAuth state token in Flask session

查看:22
本文介绍了在 Flask 会话中存储 oAuth 状态令牌的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

一些关于 oAuth 的教程使用 Flask 会话在 Flask 会话中存储状态参数和访问令牌.(Brendan McCollam 来自 Pycon 的非常有用的演示就是一个例子)

A couple of tutorials on oAuth use the Flask session to store state parameters and access tokens in the flask session. (Brendan McCollam's very useful presentation from Pycon is an example)

我知道 Flask 将会话存储在客户端的 cookie 中,并且它们很容易暴露 (参见 Michael Grinberg 的 how-secure-is-the-flask-user-session).我自己尝试过,并且能够看到令牌过期等.

I understand that Flask stores the session in cookies on the client side and that they are fairly easy to expose (see Michael Grinberg's how-secure-is-the-flask-user-session). I tried this myself and was able to see the token the expiration, etc.

将状态和令牌存储在烧瓶会话中是否正确还是应该将它们存储在其他地方?

Is it correct to store the state and tokens in the flask session or they should be stored somewhere else?

代码示例:

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

推荐答案

我认为有些教程过度简化以显示更简单的代码.一个好的经验法则是仅将会话 cookie 用于应用程序和用户浏览器必须知道的信息,而不是私有的.这通常会转换为会话 ID 和其他可能的非敏感信息,例如语言选择.

I think some tutorials over-simplify in order to show simpler code. A good rule of thumb is to use session cookies only for information that MUST be known by your application and your user's browser, and is not private. That normally translates into a Session ID and possibly other non sensitive information such as a language selection.

根据经验法则,我建议在每个标记旁边添加:

Applying that rule of thumb, I'd suggest the next to each of the tokens:

  1. 授权令牌:根据定义,用户和应用程序都知道此数据,因此在 cookie 中公开它不应该是一个安全问题.但是,一旦获得访问代码,就没有必要保留此令牌,因此我建议不要将其保留在本地或 cookie 中.

  1. Authorization Token: this data is by definition known to both the user and the application, so it shouldn't be a security concern to expose it in the cookie. However, there really is no need to keep this token once you're given an access code, so I advice against keeping it locally or in your cookies.

访问代码:必须将这些数据视为机密,并且只能由您的应用程序和提供商知道.没有理由将其告知任何其他方,包括用户,因此不应将其包含在 cookie 中.如果您需要存储它,请将其本地保存在您的服务器中(可能保存在您的数据库中,引用您的用户会话 ID).

Access Code: this data must be considered secret, and must only be known by your application and the provider. There is no reason to make it know to any other parties, including the user, therefore it should NOT be included in cookies. If you need to store it, keep it locally in your servers (perhaps in your database, referencing your users session ID).

CSRF 状态令牌:理想情况下,此数据作为隐藏表单字段包含并针对服务器端变量进行验证,因此 cookie 似乎是不必要的复杂化.但我不会担心这些数据是否在 cookie 中,因为它无论如何都是响应的一部分.

CSRF State Token: this data is ideally included as a hidden form field and validated against a server side variable, so cookies seem like an unnecessary complication. But I wouldn't be concerned about this data being in a cookie, since it's part of the response anyways.

请记住,有一些扩展,例如flask-sessions,实际上相同的代码使用服务器端变量而不是cookie变量.

Keep in mind there are extensions such as flask-sessions, with which practically the same code uses server side variables instead of cookie variables.

这篇关于在 Flask 会话中存储 oAuth 状态令牌的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆