V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
leonwong
V2EX  ›  程序员

我想知道token和sessionid的区别是什么

  •  
  •   leonwong · 2013-08-23 15:19:59 +08:00 · 43654 次点击
    这是一个创建于 4117 天前的主题,其中的信息可能已经有所发展或是发生改变。
    我对token的概念其实是很模糊的,大概知道为了防止CSRF的攻击,服务器创建session时会随机生成一个token值,存入session中,然后网页前端请求的时候会附带token信息,服务器会做匹配,但是不清楚,这和sessionid的匹配有何区别?另外网页前端如何获取token呢?
    42 条回复    2017-05-15 22:33:43 +08:00
    zzNucker
        1
    zzNucker  
       2013-08-23 15:25:21 +08:00   ❤️ 1
    form token的话一般会存在form元素里的
    leonwong
        2
    leonwong  
    OP
       2013-08-23 15:26:27 +08:00
    @zzNucker 如果不用form提交,而是用js提交ajax参数,这样不需要token吗?
    PrideChung
        3
    PrideChung  
       2013-08-23 15:41:03 +08:00   ❤️ 1
    搞清楚CSRF攻击的原理就行了。session id能够标识一个用户,却无法知道该用户提交的表单是自愿主动提交的,还是被骗去点了个链接,被恶意的JS提交的,所以才需要CSRF token。
    siw
        4
    siw  
       2013-08-23 16:02:27 +08:00
    sessionid 概念上就是一个 token 来的

    无论是哪一个, 都用来识别来源请求
    服务端和客户端产生链接就叫个session

    而在网页HTTP的范围里, sessionid 就相当于cookies 来作为来源识别判断请求
    每次浏览器request到服务器, 会自动传送 Cookies: xxx HTTP值
    而Token 则是必须自己添加到请求, 无论是往 GET 还是POST

    说错别喷
    leonwong
        5
    leonwong  
    OP
       2013-08-23 16:05:37 +08:00
    @PrideChung 你这个解释很到位了已经
    leonwong
        6
    leonwong  
    OP
       2013-08-23 16:06:51 +08:00
    @siw 你的解释我大概懂了,那么服务器该如何获取session中的token值呢?
    leonwong
        7
    leonwong  
    OP
       2013-08-23 16:07:58 +08:00
    @PrideChung

    @siw
    我还想问的是客户端如何获取token值呢?不是服务器,说错了
    siw
        8
    siw  
       2013-08-23 16:12:13 +08:00
    如果你在v2ex回复的时候, 看下原码里面有个叫
    siw
        9
    siw  
       2013-08-23 16:13:18 +08:00
    如果你在v2ex回复的时候, 看下原码里面有个叫
    <input type="hidden" name="once" value="">
    那个 once 里的value 就是个token. 用firebug看看吧
    leonwong
        10
    leonwong  
    OP
       2013-08-23 16:18:05 +08:00
    @siw 这个意思就是从服务器端取出token值存入隐藏域中吧,这应该是通过ajax实现的吧?但是我有一个疑问,这个取值是在用户登录之后一次性取值之后存在客户端,以后每次请求都会发送token值?还是说我每次请求都要取一次token,然后传token给服务端?
    siw
        11
    siw  
       2013-08-23 16:23:30 +08:00
    V2ex 没有用ajax。。。
    每次请求它就会给你新的token
    leonwong
        12
    leonwong  
    OP
       2013-08-23 17:10:53 +08:00
    @siw 刚才我看了那个隐藏域中的值,我刷新后发现值没有发生改变,也就是说,刷新的时候并不是给隐藏域赋值的时机,那是通过什么方式,什么时机下给隐藏域赋值?
    zzNucker
        13
    zzNucker  
       2013-08-23 17:22:16 +08:00
    @leonwong 没关系 token并不是用来防止重复发帖的
    理论上来说只要保证用户提交时会消耗掉一个token就行了

    token由服务端产生 与session中的token值比对
    leonwong
        14
    leonwong  
    OP
       2013-08-23 17:43:17 +08:00
    @zzNucker 原来是这样,那就是我每次请求完的时候,session中token值就开始变化,并且赋值给前端咯?
    PrideChung
        15
    PrideChung  
       2013-08-23 18:46:52 +08:00
    @leonwong 哪有这么复杂,连AJAX都出来了。服务器在生成表单的时候同时生成一个CSRF token,插入到表单的一个hidden field里面,并且把这个token记录在服务器端,通常是用户的Session数据里面。客户端啥都不用干,照常提交表单。当表单被提交的时候,服务端检查一个表单里面的token跟自己之前记录下来的是否匹配,匹配才继续处理。
    undeadking
        16
    undeadking  
       2013-08-23 19:03:17 +08:00
    估计楼主是只前端,对服务端不怎么了解.下面是一个php库的token实现,其实很简单的.

    http://flourishlib.com/docs/fRequest#PreventingCSRFSecurity
    leonwong
        17
    leonwong  
    OP
       2013-08-24 10:01:14 +08:00
    @PrideChung
    @undeadking
    我是一个学生,还在学习中,因为我用的是纯静态页,不能范围取值,我能想到给表单赋值的方法只有ajax,我看了那个连接的内容,php一个范围取值就实现了hidden的赋值,的确很方便,如果我这种情况,改用动态页应该更合适吧
    undeadking
        18
    undeadking  
       2013-08-24 11:22:57 +08:00
    @leonwong 防止CSRF这种东西是必须靠服务端来做的,纯静态页面压根就不存在被攻击的问题吧.

    表单中的hidden字段是针对html的from表单提交来搞的.对于js和移动客户端来说,这种验证很麻烦,会导致进行操作之前还要先读一次html,所以API请求一般会直接在参数里面搞个token值来做验证,这就可能和session完全无关了
    PrideChung
        19
    PrideChung  
       2013-08-24 19:01:41 +08:00
    @leonwong 纯静态页的话,服务器根本就无法处理表单,还哪用防什么CSRF攻击。
    daoluan
        20
    daoluan  
       2013-08-24 19:51:58 +08:00
    token 一般是做单点登录用,session 可能需要保存用户的信息。
    leonwong
        21
    leonwong  
    OP
       2013-08-24 23:09:07 +08:00
    @undeadking
    @PrideChung
    我是用JQuery.ajax来处理纯静态页面表单值,所以我也需要考虑CSRF攻击。不知这种处理方式常见不?
    另外我对我这样的做法的安全性很质疑,不知除了token以外还有什么需要改进?或者说一般的安全措施是什么?
    zzNucker
        22
    zzNucker  
       2013-08-24 23:22:58 +08:00
    @leonwong 你为什么质疑 说出来听听吧

    你这个如果前台页面完全无法输出信息的话是有点困难 因为这样意味着你的页面的所有东西都是完全可以直接构造出来的。。。。
    binux
        23
    binux  
       2013-08-25 00:03:13 +08:00   ❤️ 7
    说那么多token,session的。叫token的多了去了,这些概念都是伪的。
    对于HTTP协议来说,就是url,header,body
    对于WEB页面来说,就是url,form/post body,cookie

    好了,现在有的就是这么多东西,要怎么用呢?

    首先是第一个问题,HTTP请求是无状态的,我怎么知道谁是谁?
    解:让用户每次访问的时候告诉你它叫什么,怎么告诉?url,form/post body,cookie

    然后是第二个问题,用户访问的时候说他自己是张三,他骗你怎么办?
    解:在服务器端保存张三的信息,给他一个id,让他下次用id访问。id保存在url,form/post body,cookie中。这叫做session

    现在是第三个问题,用户提交了一笔订单,你怎么保证他是在你的订单页面提交的?(referer可能是一个办法)
    解:在你订单页面中放入一个加密的信息,只有真正打开了订单页才能知道,提交的时候将这个信息返回回来。这个东西,可以被叫做token
    PrideChung
        24
    PrideChung  
       2013-08-25 00:39:30 +08:00 via iPhone
    @leonwong jQuery处理表单,你是让浏览器自己跟自己玩?既然是填表单你总要Post到某台服务器上的吧,让服务器来做CSRF不就完了,有jQuery什么事。
    leonwong
        25
    leonwong  
    OP
       2013-08-25 09:08:44 +08:00
    @PrideChung 我用jQuery.ajax提交到后台某action,不是自己跟自己玩
    leonwong
        26
    leonwong  
    OP
       2013-08-25 09:14:03 +08:00
    @zzNucker 前台页面虽然是静态的,但是可以在静态页面加载的时候通过ajax向后台请求数据,可以达到动态页面效果。我的质疑是,如果有人获取到了我的cookie,并且知道了sessionid,就可以通过伪造请求来请求数据,所以我觉得安全性极差,可是不知如何改善?
    leonwong
        27
    leonwong  
    OP
       2013-08-25 09:20:21 +08:00
    @binux 这位大侠解释的通俗易懂啊,具体实现我得细细琢磨,感谢
    cxh116
        29
    cxh116  
       2013-08-25 10:03:10 +08:00
    测试CSRF提交
    zzNucker
        30
    zzNucker  
       2013-08-25 10:15:18 +08:00
    @leonwong 没用 你ajax请求数据的时候还是会造成CSRF 这样就没办法达到Form Token效果了
    除非你在发第一个请求的时候服务器就能识别出是不是用户自己发的
    cxh116
        31
    cxh116  
       2013-08-25 10:17:05 +08:00
    你可以访问这个页面看看
    http://hikitty.duapp.com/v2ex_test.html

    因为v2ex有了token,就是once表单元素,是个hidden input,所以你访问这个页面必须得输入正确的once才能发表成功.
    你需要把页面上的once字段提取出来,再手动输入进去.

    如果没有once字段,那别人一访问此页面,就可以用js实现,自动调用表单的submit,从而发表一条评论.
    undeadking
        32
    undeadking  
       2013-08-25 11:45:54 +08:00
    @leonwong 所以我已经说了,这个东西必须由服务端来实现,纯静态页面是搞不了的.如果ajax请求的后台要没有搞token验证,无论你怎么折腾js都是白搭.在架构上一开始你的考虑就错了.

    初学者没必要在所谓的安全上钻太深,先把基础打好,能把功能做出来才是首要的
    PrideChung
        33
    PrideChung  
       2013-08-25 12:38:46 +08:00
    @leonwong 如果连cookies都被人截了,那搞什么都白搭。CSRF token本来就不是用来应对种情况的,要保护cookies你应该用HTTPS。
    leonwong
        34
    leonwong  
    OP
       2013-08-25 13:43:51 +08:00
    @zzNucker
    我是这样的,我将用户的id存在session中,每次请求利用sessionid保持session,也就是说,每次请求都能够确保是该用户发送的请求,因为session里有用户id,然后就返回对应用户json进行数据处理。我已经实现了功能,可是困惑就是不知道这种方式合理不合理?我本来也觉得纯静态实现很不可思议,但是的确也能满足业务功能,那么我想ajax也可以把hidden值提交给服务器,想来想去也没什么不妥。

    @undeadking 我的业务功能已经实现了,所以我要多考虑架构和安全,我也觉得我很欠考虑,但是纯静态页面配合js实现了我想要的,token验证我想也可以通过ajax,可能性能上会有劣势,但是功能上跟动态区别不大,就当我在静态页面上的学习和探索,所以可能我会钻牛角尖。
    leonwong
        35
    leonwong  
    OP
       2013-08-25 13:45:56 +08:00
    @cxh116 我还没得用电脑现在,等用电脑,立马拜读帖子
    leonwong
        36
    leonwong  
    OP
       2013-08-25 13:48:28 +08:00
    @PrideChung 那如果按照这个说法,我觉得如果cookie没被窃取的话,html配合ajax实现数据请求的安全性还算比较高啊
    zzNucker
        37
    zzNucker  
       2013-08-25 13:51:17 +08:00
    @leonwong 就算是CSRF劫持的请求也会带上网站的cookie的,所以光验证session并不能避免CSRF
    token的关键是在于你在发送请求的时候一定要保证你是读取了这个页面的。。 而不是凭空就发送请求
    PrideChung
        38
    PrideChung  
       2013-08-25 14:42:56 +08:00
    @leonwong 看了半天我都没看懂你程序的架构是怎样的,难道你最后处理提交表单的那台服务器根本不归你管?

    另外数据传输的安全性跟是否Ajax请求无关,只要用HTTP的话就是明文传输,一样能够被截。
    leonwong
        39
    leonwong  
    OP
       2013-08-25 15:20:24 +08:00
    @zzNucker
    @PrideChung
    token原理我已经理解了,谢谢,也谢谢楼上回答问题的各位,怪我不好,因为这两天没得用电脑,手机打字不方便,所以很多情况没说明白,等我可以用电脑的时候,我再发一帖,我会系统说明我使用的架构和平台,目的是讨论一下网站安全问题,我也会参考资料,谢谢你们的耐心解答
    etata
        40
    etata  
       2016-08-25 16:38:48 +08:00
    @binux
    还是没说为什么用 token ,不用 sessionid 啊。既然唯一 id ,放在 cookies 也是放,放在 hidden 里也是放。再说 sessionid 在 cookies 禁止的时候也是放在 url 中或者表单中啊。 为什么不统一用一个呢?
    binux
        41
    binux  
       2016-08-25 16:49:25 +08:00
    @etata 唯一 id 一般是固定的, token 可以不是固定的,而是每次访问随机生成的。当然你要把 seesionid 用作 token 也不是不可以。
    gelilaohuang
        42
    gelilaohuang  
       2017-05-15 22:33:43 +08:00
    我试下 hidden 的 value
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2569 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 27ms · UTC 02:56 · PVG 10:56 · LAX 18:56 · JFK 21:56
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.