2016-02-22 23 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