2016-02-22 26 views
1

根據該文檔在https://www.godoc.org/golang.org/x/oauth2#Config.AuthCodeURL何時對oauth2中的授權碼/狀態進行隨機化?

...狀態,以防止CSRF攻擊用戶的令牌。你必須始終提供一個非零串...

,並在http://tools.ietf.org/html/rfc6749#section-10.12

...發送到重定向URI端點的任何請求,包括結合請求的值...

然而,這是專門在流程中沒有會話數據的部分,即用戶沒有登錄,並且只有在顯示匿名頁面時才生成授權碼。

那麼該值如何隨機化並在回調時進行比較?它是每個服務器隨機化的靜態值嗎?

回答

1

狀態

推薦。客戶端使用的不透明值,用於在請求和回調之間維護 狀態。授權 服務器在將用戶代理重定向回 到客戶端時包含此值。該參數應該用於防止 第10.12節中描述的跨站請求僞造。

RFC 6749

您使用state,以確定從授權服務器回調發送的請求匹配。如果沒有state攻擊者可以使用您沒有請求的隨機訪問令牌調用您的回調URL。通過state,您知道被叫回叫是對您提出的請求的迴應。

所以你隨機發送state每個請求,你發送並跟蹤它,直到你收到匹配的回調。只要它不能被猜測,它可以是任何你想要的。

一個簡單的方法是利用rand.Reader和Base64編碼的結果:

func state(n int) (string, error) { 
    data := make([]byte, n) 
    if _, err := io.ReadFull(rand.Reader, data); err != nil { 
     return "", err 
    } 
    return base64.StdEncoding.EncodeToString(data), nil 
} 
+0

的事情我感到困惑,雖然是「跟蹤它,直到......」的一部分。假設可能有多個同時發生的請求,不能真正將其設置爲全局變量。你是否建議添加/刪除數據庫行或什麼? – davidkomer

+0

您可以使用'map [string] user.Identifier'來存儲您的狀態以及用戶標識符:'m [state] = userId'。當回調到達時,在地圖中查找用戶標識符,並將接收到的訪問令牌與其關聯。之後從地圖上刪除密鑰。您可能希望使用某種形式的過期緩存來刪除一段時間內尚未回叫的狀態。 – Danilo

+0

明白了 - 所以是的,和db一樣的想法,但不需要像memcached那樣是鐵血的? – davidkomer