该网站并非前后端分离项目,通过 Sesssion 判断是否登录,并且比较多 HTML 代码是通过 PHP 控制显示的,也有一些数据是通过 Ajax 请求的。
现在公司要求,即使用户 禁用 Cookie 也需要让用户能正常登录、使用(具体为什么也不好说)
PS:因为页面比较多,暂时也不太现实改成前后端分离的模式
用户登录,跳转的 URL 后面再加上如 token
参数,token
由服务器生成长度 32 位,并储存在 Redis 里,TTL 设置为 86400 秒,大概结构就是
key | value |
---|---|
user:info:服务器生成的 Token |
序列化后的一些用户数据如用户 ID等数据 |
然后计划用 JS 将页面中 a
标签链接,如果包含了项目域名 www.baidu.com,如:https://www.baidu.com/test
的后面追加一个 token
参数(取当前页面地址栏 token 值),就变成了:https://www.baidu.com/test?token=xxxxxxxxxx
就像之前说的,页面中还有 Ajax 请求的,接口有 CSRF
验证,因为禁用了 Cookie 故请求失败( HTTP 状态码 419 ) 。暂时只想到的就是 Ajax 请求的时候也加上 Token 然后中间件之类的改一下验证
以上的做法不知道有大家有什么看法(比如有无安全方面的问题),或者有更好的建议
先谢谢大家了 : )
1
westoy 2021-03-03 22:02:16 +08:00
php.ini 里有参数可以支持通过 GET 传递 session id
不过这个可能会泄漏 session id, 导致安全问题 比如某人把带自己 session id 的 URL 发给其他人, 或者你们网站可以插入外部资源, 对方通过日志 referer(可以设置同源策略, 但部分老浏览器就糟了) |
2
NowTime OP @westoy 你这个建议可以,这样省了自己再改动代码 。
就是你说的安全问题,可能是个问题,不过我想了下,能否将用户一些特征如 IP 、UA 写入 Session,然后在判断是否登录那里,再判断下当前访问的 IP 、UA 是否与 Session 里的相同 |
3
westoy 2021-03-03 22:24:14 +08:00
@NowTime
能啊 但是捆绑 IP 会带来一个副作用, 有些小区宽带和二级运营商的用户 IP 是满地图飞的, 不是固定的 捆绑 UA 的话, 对方能通过跨站资源获取触发访问的老浏览器用户的 session id, 那也能获取 UA 啊 |
4
Rocketer 2021-03-04 00:09:51 +08:00 via iPhone
这个还是有状态验证,只是 session id 的传递方式变了。
我有个想法不知是否可行——既然所有的页面都是服务端渲染的,那你就在所有页面的 URL 后面加上个 token,然后服务端通过 referer 来读取。这样只需在出入口加两个中间件,出口负责加尾巴,入口负责读取尾巴并重建 session 就可以了,原有程序基本无需改动。 当然,referer 是不可靠的,但并没有比楼主的方法更不可靠。实在需要安全的话可以做成一次一密,即 token 使用一次就作废,下个页面的尾巴是新 token,这就无机可乘了。 |
5
also24 2021-03-04 00:16:28 +08:00
贴两个链接供参考:
https://www.php.net/manual/zh/session.idpassing.php https://www.inbreak.net/archives/171 另 @Rocketer #4,实际上你这恰好说到了把 session id 写入 URL 的风险之一: Referer 由于没有跨域限制,在页面引用、请求了其它站点的资源,或者跳转到了外链的时候,session id 会更容易泄漏。 |
6
falcon05 2021-03-04 00:21:39 +08:00 via iPhone
不能存放在 Cookie,那就将 token 存 localstorage,每次请求附在请求头,有些 jwt 就是这样用的
|
8
falcon05 2021-03-04 00:23:30 +08:00 via iPhone
不过不是单页应用,这样改的话需要点技巧
|
9
just1 2021-03-04 01:58:04 +08:00 via Android
额
想到一个奇技淫巧 原有页面通通用 iframe 来加载,sessionid 在 get 参数里。父页面用 history mode 来更新 URL,url 是 iframe 的地址去掉 session 。这样就能够不在浏览器地址栏显示了 不过 ajax 还得处理一下,那个得手动带上 sessionid |
10
imdong 2021-03-04 07:52:23 +08:00 via iPhone
https://www.qs5.org/Post/653.html
曾经写过这样一篇文章,利用缓存机制实现。 |