首頁  >  問答  >  主體

php - api 使用session替代token 的利弊在哪?

最近写app的api,使用laravel 框架的session替代了传统的存贮到数据库的token作为校验登录用户的方法!
以下是我们目前的做法

  1. 登录后后台生产session,会往返回信息head头里写一个set_cookie

  2. ios和安卓 会从head头里得到拿到这个cookie的东西

  3. 然后再请求需要登录的地方的时候,ios和安卓会把cookie放到head头里,让框架完成自我的校验

ps:

  1. 有人说不安全

  2. 有人说不好管理

  3. 有人说性能问题

有谁具体研究过,请帮我分析分析其利弊

我个人认为的观点:

  1. 说session不安全的,感觉有点牵强,假如真的一点不安全的话,那网站也就完全被暴露了,而且laravel的session也是有自己加密的方式,不是直接暴露的!

  2. 有人说不好管理,放在redis里了,我不太知道不好管理在哪里。

  3. 性能问题,session可以存贮的位置有很多,mysql,文件,redis,我觉得性能也不是问题。我也不知其弊端在哪里,

有谁具体研究过,请帮我分析分析其利弊
也请大家有想法的各抒己见,我们一起讨论下

黄舟黄舟2724 天前821

全部回覆(11)我來回復

  • 迷茫

    迷茫2017-04-11 10:34:43

    在存储过等同的情况下,在只是简单运用上,我只能说session与token没有本质的区别,二者不都是一串被加密过的字符串,拿他来做校验都一样。

    以上,是因为你把token拿来当作用户是不是当事人做这么一个简单的校验的情况下。

    当然,如果我们抛开一些比较极端的操作,token比session也有很大的区别:

    • token可以存在任何位置(cookie、local storage)

    • token比session更容易跨域。

    • CORS预检查时token比较更简单。

    • token有更多的控制权,比如当token过期时,你可以拿通过刷新token,让用户一直保持有效登录。

    等……其实如果你只是单纯拿着token做一下自己网站内用户登录检验的话是无太多区别的。

    但假如token指的是OAuth Token提供认证和授权这类机制的话,那么就可以把session甩开N条街了,甚至是已经完全是两种不同的概念。

    假设有这么一个场景,你们用户在你们网站产生的订单,而另一家公司是专业ERP公司;而你的用户希望他的订单同时授权给这家ERP公司使用的情况下,难道你希望用户拿在你家网站的用户名和密码给这家ERP公司吗?

    这时候OAuth Token就有意义了,OAuth Token的授权大概是这样的:

    • ERP需要调用我们提供的登录界面。

    • 用户输入用户名和密码后,我们再向ERP发送一个TOKEN。

    • ERP拿TOKEN换数据。

    总之,如果你只是在自己网站内部上使用二者没有什么太多区别。而如果你的API是在不同终端上使用,token会更方便。

    回覆
    0
  • 高洛峰

    高洛峰2017-04-11 10:34:43

    1 首先session和token 原始出发点就不一样,如果单纯为了校验用户登录可以直接使用session,不存在什么安不安全,因为session他只是一个会话通讯机制而已。token通常是用自己定义的一些算法加密生产,常见的是以post或者get提交过来的参数加以运算和服务器token值做比较,防止参数篡改造成恶意攻击,也可以将用户信息带入算法中起到用户校验的功能。

    比如我的一个网址id存在sql注入
    不加token时:
    http://www.xxx.com/index.php?id=1
    攻击者可以通过sql注入,入侵服务器
    有token时,假设你token=md5($id."aabbcddee");
    http://www.xxx.com/index.php?id=1&token=747e948ded9790b345f6342881ecd259
    如果我们篡改了id参数
    http://www.xxx.com/index.php?id=1 and 1=1&token=747e948ded9790b345f6342881ecd259
    服务端验证就无法通过
    $id="1 and 1=1";
    md5=($id."aabbcddee")就不等于token的值747e948ded9790b345f6342881ecd259

    此时token起到了防止参数污染的安全作用
    2 你担忧的2,3 纯属扯淡,session往往和token共存的。session负责会话,token侧重于复制安全访问。

    回覆
    0
  • PHPz

    PHPz2017-04-11 10:34:43

    我的理解不是 session 不支持, 是因为分布式的原因导致 session不能在不同的服务器上共享。所以要移到 DB。或者是前端的TOKEN.

    回覆
    0
  • 大家讲道理

    大家讲道理2017-04-11 10:34:43

    我觉得session完全可行,你说的3个问题session都没有。唯一阻碍使用session的可能是API的客户端开发,因为sessionid会通过cookie来保存和传输,一般客户端HTTP组件不支持cookie,想支持起来需要开发,不如token来的方便。

    回覆
    0
  • PHP中文网

    PHP中文网2017-04-11 10:34:43

    在多台 WEB 服务器的情况下,dns 轮询或者负载均衡设备会将请求“随机”转发到某一台 WEB 服务器,sid 如果存在本机(php 的 session_start() 默认的存放方式)下可能会出问题,如果存在统一的 memcached/redis/db/ 里则可以避免这个问题,但是又会有单点性能问题。

    token 的话解开就可以用,分布式部署也不会有问题,但是 token 的加密算法存在安全性问题,可逆算法终究是不安全的, 在 《白帽子谈 WEB 安全》中有讲到各种主流可逆算法的攻击方法。这块加密强度和安全性成正比,要高安全性,采用较高强度的算法,性能会损失些。Xiuno BBS 4.0 中采用的 xxtea 加密算法在性能和安全性上比较平衡,适合 WEB 项目,有兴趣可以了解下。

    现在流行的做法是用 TOKEN,这样对于 RESTful 风格的接口设计比较对胃口。

    各有利弊,自行权衡吧。

    回覆
    0
  • PHPz

    PHPz2017-04-11 10:34:43

    1.说不安全,这个有点牵强,但是使用session做用户的验证,session生成一个唯一的id存放在客户端的cookie中作为唯一的标识,换句话说,假如客户端停掉了cookie的话,那么验证的就会出现问题。
    2.至于使用token,第一token的加密方式必须严谨,第二需要为token生成一个有效时间。第三redis的性能虽然很高,但万一重启redis时候,验证就会出现一个很严重的问题,就就是说当redis重启时候必须停了服务器运营,除非你有redis的主从服务器。假如存储数据库,那就更加不实际,应该会受到很大的性能限制,每次用户需要发出请求时间,都要访问mysql服务器作验证。
    所以各个都有利与弊

    回覆
    0
  • 高洛峰

    高洛峰2017-04-11 10:34:43

    对于 api 来说,token 通过 header 传输,对应的用户数据放在 redis 里,这样移动端保存 token 比较方便,移动端保存 cookie 不是很容易,浏览器里还是用 cookie + session 方便,集群中共享 session 不是啥问题。

    回覆
    0
  • 黄舟

    黄舟2017-04-11 10:34:43

    Web请求没有绝对的安全
    http请求都是可以伪造的,所以不存在session跟这种token这种谁安全谁不安全的说法

    http接口只能验证请求的正确性以及做到部分的限制访问频率,服务端是不能知道到底是真实的用户请求的 还是别人为了爬你数据伪造的请求。app端做加固 防止app被反编译,然后参数用一个存在app跟服务端同样的key rsa加密下(高深的我也不懂,就简单用下这种对称加密可以防止很多小白了)
    我是建议用token这种方式好一点 现在有一种比较流行的jwt 你可以试下 https://jwt.io/

    回覆
    0
  • 天蓬老师

    天蓬老师2017-04-11 10:34:43

    session id也是一种token,你的理解是对的。

    回覆
    0
  • 黄舟

    黄舟2017-04-11 10:34:43

    其实标准的OAuth只是比较规范,而且能够作为标准接口来调用,就是外部的服务如果需要也可以调用就这样,权限也比较好控制。。。
    实质上差不多,所以没有说你用token来弄不行,安全性要注意就是了。。

    回覆
    0
  • 取消回覆