分离OAuth2与Web服务器:跨域登录状态同步实现方案咨询
这个场景的核心是同主域名下的子域Cookie共享,再配合OAuth授权服务的状态跟踪,咱们一步步理清楚整个流程的底层逻辑:
第一步:配置跨子域共享的登录Cookie
当用户在web.example.com完成登录后,这个站点会设置一个登录态Cookie,关键是要把Cookie的Domain属性设为.example.com(注意前面的点),同时Path设为/。这样一来,oauth.example.com作为同主域的子站点,就可以读取到这个Cookie。另外别忘了加上HttpOnly(防止XSS窃取)、Secure(仅HTTPS传输)这些安全属性,保障登录态的安全性。第二步:授权请求的状态暂存
当用户访问oauth.example.com/authorize但未登录时,oauth.example.com会先生成一个OAuth2标准的state参数(用来防止CSRF攻击,同时标记当前的授权请求),把这个state和当前授权请求的其他信息(比如client_id、redirect_uri)暂存在自己的会话存储里(比如Redis、后端数据库),然后把用户重定向到web.example.com的登录页面,同时把state参数也传递过去(比如放在跳转URL的查询参数里)。第三步:登录完成后的回调重定向
用户在web.example.com登录成功后,这个站点会先确认之前带过来的state参数,然后设置好跨子域的登录Cookie,接着把用户重定向回oauth.example.com/authorize,并且带上之前的state参数,让oauth.example.com能匹配到之前暂存的授权请求。第四步:验证登录态并获取用户信息
当用户回到oauth.example.com时,它会读取.example.com域下的登录Cookie,里面包含用户的会话标识(比如session ID)。然后oauth.example.com拿着这个session ID去共用的会话存储里查询,确认用户已经完成登录,同时获取到用户的身份信息(比如用户ID、用户名)。第五步:完成OAuth2授权流程
确认用户已登录且身份有效后,oauth.example.com就会继续OAuth2的后续流程:如果需要用户授权,就展示授权确认页面;如果是静默授权(提前配置好的),直接生成授权码(authorization code),最后把用户重定向回client.com的回调地址,带上授权码和state参数,整个登录授权流程就完成了。
需要注意的是,两个子站点的后端必须共用同一个会话存储(比如同一个Redis集群),这样oauth.example.com才能通过session ID查到web.example.com生成的用户会话信息。如果是跨主域的场景,这套机制就不适用了,得用其他方案比如单点登录(SSO)的Token机制,但你这个场景是同主域,Cookie共享是最高效的方案。
内容的提问来源于stack exchange,提问作者eugene

