2017-05-30 63 views
-1

我在Flask上写了一个Web应用程序,并且正在从用户处获取表单数据。在他们传递了这些数据之后,我试图用amazon自动进行身份验证。如何在重定向之后跟踪烧瓶会话?

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

  2. 的用户想用自己的Amazon帐户登录,但我试图用硒蟒蛇到的webdriver自动将它们记录在他们首先提交的信息中。

  3. 使用webdriver登录后,Amazon重定向到通过初始查询字符串传入的URL。现在重定向的URL有一个访问代码,我需要获取并使用它作为令牌认证过程的一部分。

这里的问题: 去年重定向后,我的瓶应用程序失去我存储在会话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) 
+0

我无法重现您的问题。通过外部身份验证重定向不会导致浏览器丢弃与我的网站相关联的会话Cookie。请[edit]包含[mcve]。 – davidism

+0

@davidism添加一个最小的例子来显示我有问题。请注意,我使用selenium webdriver自动执行用户的登录过程。 – TotemPole

回答

0

我能找到解决的办法有作出OAuth2要求亚马逊在不同页面之间的用户的信息仍然存在。我假设其他网站的身份验证过程非常相似,因此我添加了我使用的解决方案。

  1. 创建DB会话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. 从查询字符串中获取STATE并使用它从数据库或缓存中获取所需的所有用户信息。

亚马逊的解决方案:

  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