【问题标题】:How to keep track of flask session after a redirect?重定向后如何跟踪烧瓶会话?
【发布时间】:2017-05-30 18:25:47
【问题描述】:

我正在 Flask 中编写一个 web 应用程序,并且我正在从用户那里获取表单数据。在他们传入该数据后,我正在尝试使用亚马逊自动进行身份验证。

  1. 所以我发送了一个带有查询字符串的 GET,亚马逊向我发送了他们的登录页面

  2. 假设用户使用他们的亚马逊帐户登录,但我正在尝试使用 selenium python webdriver 自动将他们登录到他们首先提交的信息中。

  3. 在他们使用 webdriver 登录后,Amazon 会重定向到我通过初始查询字符串传入的 URL。并且重定向的 URL 现在有一个访问代码,我需要获取该代码并将其用作令牌身份验证过程的一部分。

问题来了: 在最后一次重定向之后,我的 Flask 应用程序丢失了我存储在会话 cookie 中的所有内容。我的意图是使用会话来跟踪 user_id,以便我可以使用检索到的访问代码更新用户记录。

那么如何在重定向到外部登录站点后不丢失 Flask 中的会话?

更新(代码示例):

@app.route('/index', methods=['GET', 'POST'])
def index():

    if request.method == 'POST:
        # user is logged in and added to database here
        configs = request.files['config']
        session_id = b64encode(os.urandom(24))
        session['user_config'] = configs
        session['session_id'] = session_id

        user = User.query.filter_by(email=configs['email']).first()
        if user is None:
            # add user to database with data in configs dict file
            # ...
            return redirect(url_for("app.get_auth_code"))
        else:
            # no need to authenticate user
            # continue work as expected
            # ...



@app.route('/lwa', methods=['GET', 'POST'])
@login_required
def get_auth_code():

    auth_url = "https://www.amazon.com/ap/oa"
    redirect_uri = "http://localhost:5000" +  url_for("app.authresponse")

    sd = json.dumps({
        "alexa:all": {
            "productID": session['user_config']['DEVICE_TYPE_ID'],
            "productInstanceAttributes": {
                "deviceSerialNumber": "001"
            }
        }
    })
    payload = {
        "client_id": session['user_config']['CLIENT_ID'],
        "scope": "alexa:all",
        "scope_data": sd,
        "response_type": "code",
        "redirect_uri": redirect_uri
    }

    query_str = "?" + urlencode(payload, doseq=True)
    driver = webdriver.Firefox(executable_path='/tmp/geckodriver')
    driver.get(auth_url + query_str)

    wait = WebDriverWait(driver, 10)
    amazon_sign_in = wait.until(EC.title_contains("Amazon.com Sign In"))

    if amazon_sign_in:
        username = driver.find_element_by_id('ap_email')
        password = driver.find_element_by_id('ap_password')
        submit_button = driver.find_element_by_id("signInSubmit")

        # Fill in email and password
        username.send_keys(session['user_config']['EMAIL'])
        password.send_keys(session['user_config']['PASSWORD'])
        submit_button.click()
        # driver.close()
        return redirect(url_for("app.authresponse"))
    else:
        flash("Login With Amazon page not found")
        return redirect(url_for("app.index"))

    return redirect(url_for("app.index"))


## This is the function where I lose the session for the same user  
## This is the callback route that amazon sends the auth code to after the user is logged in
@app.route('/authresponse', methods=['GET', 'POST'])
def authresponse():
    code = None
    if request.method == 'GET':
        code = request.args.get('code', None)
        if code:
            user = User.query.filter_by(session_id=session.get("session_id")).first()

            if user:
                user.auth_code = code
                db.session.commit()

                # retrieve access token with POST request
                url = "https://api.amazon.com/auth/o2/token"
                payload = {
                    "client_id": user.client_id,
                    "client_secret": user.client_secret,
                    "code": code,
                    "grant_type": "authorization_code",
                    "redirect_uri": "http://localhost:5000" + url_for("app.authresponse")
                }
                r = requests.post(url, data=payload, timeout=5)
                if r.status_code == 200:
                    print r.text
                    return r.text
                else:
                    print r.text, r.status_code
            else:
                print "User not found"
                flash("Auth code not found.")

    return """code:<div id="token">{}</div>""".format(code)

【问题讨论】:

    标签: python flask webdriver phantomjs


    【解决方案1】:

    当向亚马逊发出 Oauth2 请求时,我能够找到一种解决方案,让用户的信息在不同页面之间持续存在。我假设其他网站的身份验证过程非常相似,所以我添加了我使用的解决方案。

    1. 创建会话 ID 并存储在数据库或缓存中
    2. 通过“状态”字段将 OAuth2 请求的状态传递到有效负载中,将状态分配为会话 ID

       payload = {
      
                  "state": session_id,
                  "client_id": user.client_id,
                  "client_secret": user.client_secret,
                  "code": code,
                  "grant_type": "authorization_code",
                  "redirect_uri": "http://localhost:5000"
              }
      
    3. 在身份验证服务将访问令牌发送到的重定向 url 中,STATE 应该出现在重定向 URI 的查询字符串中。

    4. 从查询字符串中获取状态并使用它从数据库或缓存中获取您想要的所有用户信息。

    亚马逊解决方案:

    1. https://developer.amazon.com/public/apis/engage/login-with-amazon/docs/dynamically_redirect_users.html

    2. https://developer.amazon.com/public/apis/engage/login-with-amazon/docs/cross_site_request_forgery.html

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-07-18
      • 2020-09-05
      • 2015-03-01
      • 2021-10-09
      • 2018-08-18
      • 1970-01-01
      • 2017-05-21
      • 1970-01-01
      相关资源
      最近更新 更多