2015-10-15 151 views
2

我在正確實施OAuth時遇到了麻煩。 我使用客戶端/ API架構(Angular爲Front,Node.js爲back),我希望用戶僅使用Google OAuth身份驗證進行登錄。Google OAuth2流和id_token刷新

這裏是什麼,我認爲是暫時的正確方法(告訴我,如果我誤解的東西):

  • 角開一個谷歌彈出,詢問用戶的同意。
  • 一旦用戶同意,Google授權服務器將發回驗證碼。
  • 此驗證碼被轉發到API端點。
  • 然後,API要求Google授權服務器將此代碼交換爲access_token,id_token和refresh_token。
  • Google發送這3個令牌。
  • API使用的access_token從谷歌API檢索用戶
  • 的API仍然存在用戶

這裏是小dillema,在我看來,在的access_token和refresh_token應該存儲到數據庫和id_token應該發回給Angular客戶。 這樣,它將允許API在Google API中請求資源,並且如果令牌過期,則可以使用refresh_token來請求新的令牌。 客戶端,id_token被嵌入到所有請求中,從而允許API識別客戶端並通過https://www.googleapis.com/oauth2/v3/certs的Google證書驗證其身份驗證。

假設這是正確的方式來使用令牌,我怎麼能處理id_token過期,因爲客戶端沒有任何刷新令牌?

謝謝!

回答

0

我這樣做有點不同(儘管我有相同的基本架構)。

  • Angular決定用戶需要登錄並顯示登錄彈出窗口。
  • 登錄彈出窗口中的URL是而不是由角度服務,但直接從後端服務器運行:/auth/google。 (我個人使用hapijs和bell)。
  • /auth/google由鈴聲插件提供服務並啓動OAUTH舞蹈。
  • OAuth技巧結果在我的節點服務器生成本地令牌結束(我只是生成隨機字節並將其存儲在映射到用戶ID的Redis)
  • 因爲初始登錄彈出被window.open,成功頁面創建(在api側生成而不是在角度上生成)可以使用window.opener.postMessage將令牌回傳給角運行時。

這樣,我所有的敏感谷歌憑據(用戶的OAuth令牌,如果需要的話,我的應用程序的API ID和祕密刷新令牌),僅是在服務器上,除了OAuth技巧繼電器時,他們在在客戶端重定向期間的URL字符串中。這是相當安全的。

然後,對於所有與api的實際用戶交互,我使用在步驟4中生成的令牌進行身份驗證。如果你願意,這可能是智威湯遜,但我不這樣做;我只是使用redis來映射'longrandostring' - > userId。例如,如果我擦除存儲了所有令牌的redis數據庫,或者我可以編寫一個lua腳本來刪除映射到特定用戶ID的所有條目,那麼我可以(例如)強制每個人重新登錄。

如果您需要刷新令牌,則可以在初始請求中將access_type=offline設置爲oauth2/auth,除非您之前已獲得刷新令牌,否則您將獲得刷新令牌作爲回覆的一部分。然後,您可以將其保留在服務器端,並根據需要獲取新的訪問令牌。如果您同時設置了approval_prompt=force,則會強制執行一個新的同意屏幕並保證刷新令牌(但在向用戶授予一定數量的刷新令牌後,較舊的令牌會在同一應用程序上過期,因此最好只在真的需要)。