Rails 从一个系统跳转到另一个系统,需要保持登录状态,有啥好办法吗?

qq792326645 · 2019年04月18日 · 最后由 ericguo 回复于 2019年04月21日 · 6029 次阅读

需求&&场景

有两个系统 A 和 B,两个系统都是独立的域名,用户系统不互通,我要实现的是如果在系统 A 登录了的用户,通过 A 的链接跳转到 B 访问 B 的资源时,可以跳过登录这一步

我自己想的方案

1.首先,在 B 的 User 表里加一个字段,假设为 A_username,用来记录用户在 A 系统中的用户名

2.每次用户从 A 往 B 跳转的时候,带上 A 系统的用户名信息

3.B 收到请求之后,通过传过来的 A 的用户名去查自己的 User 表,如果不存在这个用户,那么自动创建一个 B 系统用户,如果存在,就直接自动登录

那么我这个方案会存在什么问题么?

有什么更好的方案可以推荐么?手写代码或者用相关的 Gem,如果用 Gem 的话有啥轻量一点的 Gem 可以实现我的需求吗?毕竟我的需求还是比较简单

我知道这是一个单点登录的需求,我也考虑用 Omniauth 这个 Gem,但是我发现用 Omniauth 的话我需要再 A 系统里实现一个授权机制,才能建立 A B 系统的信任关系,感觉太麻烦了(我不知道我理解的对不对,没用过 Omniauth)

原理上差不多也是这种。简单的是也可以这样做,其他方式考虑更多的是从安全性上。不应该用户名,而是用一个唯一值 uuid 加上时间戳再加个随机码,这样小规模用还是可以的。

直接传 username 会有暴力破解的问题,可以把会话相关的信息通过 JWT 传递给 B 系统。JWT 的介绍

注意 JWT Payload 只是做了 Base64 编码,相当于是明文的,所以和 B 站的通信一定要用 HTTPS。 为了增加安全性,你还可以在 JWT Payload 里面带上时间戳,B 站检查时间戳,比如超过 5 秒就判断为失效。 还可以在 B 站检查 HTTP 的 Referer 字段,只允许 A 站的访问。

简单点也不要这么省阿,至少用 hmac 给弄个签名,不然漏洞也太大了点。

gecko_gecko 回复

它是直接跳过去,SWT 应该也够用了

这是一个单点登录 (SSO) 的需求吧?

我是根据下面的文章和代码改写了一个 SSO 网站,其它的小项目网站都使用统一认证,太好用了。

这篇文章可以帮助快速理解高大上的 SSO 原理。

6 楼 已删除

我结合了一下二位大佬的想法,麻烦二位帮忙看一下这样行不行

整体还是按照之前的思路,只是有点小变化

1.为了安全性,像 @awking 所说,我传一个唯一的 uuid 过去,B 这边在 User 表中添加一个 a_uuid 字段,每次收到 uuid 后去 user 表中检查有没有匹配的 user。也就是使用一个 uuid 来建立 A 系统和 B 系统的用户之间的关系(当然,A 系统的用户表中也可以保存这个 uuid)

2.使用 JWT 来传递 uuid @gecko_gecko

samport 回复

多谢指点,我自己之后也写个 Demo 来深入理解一下 SSO,以后有问题再请教一下。不过话说你这个 SSO 的方案一定要用 devise 吗?

adamshen 回复

感谢指出,确实我这样漏洞太大了

qq792326645 回复

SSO 的话,可以参考我最近的工作,https://github.com/thape-cn/oauth2id 提供了 OAuth2, SAML 2.0, Open ID Connect 三种接入方式,这三个都是标准,系统 A 和 B 可以都接入 oauth2id,而且不要求这些系统是 Rails 写的。

当然你如果系统 A 想做 SSO Provider 也可以,但长期看不是一个好主意,各大互联网厂商基本上都把 Account 授权独立开的。

需要 登录 后方可回复, 如果你还没有账号请 注册新账号