2017-05-30 61 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