rails session cookie
2016-08-11 17:39
232 查看
Published on 2014-02-09
为了理解session,我想像了一个场景:
老年痴呆患者是没有记忆力的,我告诉他我的名字,并热情的和他打招呼。可第二次会话时,他早已忘记我的名字。
HTTP 协议也是如此,没有状态的,多个请求之间毫无关联。
把 user id 放到 session 中。
每次浏览器发起请求时捎带着cookie信息。
服务器获取 session 中的user id
服务器根据 user id 把当前用户拎出来。
cookie 只能保存4kB的信息,一个对象就可能把它撑爆了。
不要在session中保存重要的数据,因为:
用户关闭浏览器或清空cookie后,这些重要的数据会丢失。
session在客户端保存,用户可以读取这些信息。
明文展示,在客户端一览无余。
若Cookie有变,服务器通过set-cookie命令重新设置客户端的Cookie。(Response)
假如我的项目名为food,则session key的名字就是_food_session
正文
已被base64编码,很轻松就可还原为一个hash。
digest
正文只是简单的编码,并未加密的。如果用户(user_id = 13134)篡改了正文(user_id = 2),就有访问其他用户信息的风险。
为了防止cookie被篡改,每一个session字符串的尾巴上都带着一个服务器生成的digest。
若用户的content与digest不匹配,服务器就知道这个cookie是伪造的。
digest如何生成
在Rails中,secret保存在 config/initializers/secret_token.rb 文件中。
digest生成规则:content + secret token => digest
这个secret token是机密文件,一旦被坏人获取,就可以轻松的伪造cookie(很多菜鸟开源代码时往往犯这个低级错误)。
为了理解session,我想像了一个场景:
老年痴呆患者是没有记忆力的,我告诉他我的名字,并热情的和他打招呼。可第二次会话时,他早已忘记我的名字。
HTTP 协议也是如此,没有状态的,多个请求之间毫无关联。
Session的用途
session 是一串 Hash,保存在浏览器的Cookie文件中。把 user id 放到 session 中。
每次浏览器发起请求时捎带着cookie信息。
服务器获取 session 中的user id
服务器根据 user id 把当前用户拎出来。
禁忌
不要在session中保存对象。cookie 只能保存4kB的信息,一个对象就可能把它撑爆了。
不要在session中保存重要的数据,因为:
用户关闭浏览器或清空cookie后,这些重要的数据会丢失。
session在客户端保存,用户可以读取这些信息。
Cookie的数据结构
Cookie 中的值都是以key: value的形式展示的。明文展示,在客户端一览无余。
Cookie文件是动态的
客户端发起每次请求时,会捎带着cookie。(Request)若Cookie有变,服务器通过set-cookie命令重新设置客户端的Cookie。(Response)
Session 寄人篱下
session信息以键值对的形式保存在cookie中。Rails session 命名习惯是_app_session.假如我的项目名为food,则session key的名字就是_food_session
Session 中的内容
session字符串可以拆分为两部分:正文
已被base64编码,很轻松就可还原为一个hash。
1.9.3p448 :001 > require 'base64' => true 1.9.3p448 :001 > str = "BAhJIgGDeyJzZXNzaW9uX2lkIj0+IjAwZDllY2FlYWZmZGEyMzIzMjRhZmZh\nZThjMDYzMzcwYWJiMDgiLCAidXNlcl9pZCIgPT4gIjEzMTM0IiwgIl9jc3Jm\nX3Rva2VuIj0+ImNlbzRqMm9Jck9TM2dMRFBzZ3UzY0VISGV1WnlIczE2NlNp\nIn0GOgZFVA==\n" => "BAhJIgGDeyJzZXNzaW9uX2lkIj0+IjAwZDllY2FlYWZmZGEyMzIzMjRhZmZh\nZThjMDYzMzcwYWJiMDgiLCAidXNlcl9pZCIgPT4gIjEzMTM0IiwgIl9jc3Jm\nX3Rva2VuIj0+ImNlbzRqMm9Jck9TM2dMRFBzZ3UzY0VISGV1WnlIczE2NlNp\nIn0GOgZFVA==\n" 1.9.3p448 :002 > new_str = Base64.decode64(str) => "\x04\bI\"\x01\x83{\"session_id\"=>\"00d9ecaeaffda232324affae8c063370abb08\", \"user_id\" => \"13134\", \"_csrf_token\"=>\"ceo4j2oIrOS3gLDPsgu3cEHHeuZyHs166Si\"}\x06:\x06ET" 1.9.3p448 :003 > Marshal.load(new_str) => {"session_id"=>"00d9ecaeaffda232324affae8c063370abb08", "user_id" => "13134", "_csrf_token"=>"ceo4j2oIrOS3gLDPsgu3cEHHeuZyHs166Si"}
digest
正文只是简单的编码,并未加密的。如果用户(user_id = 13134)篡改了正文(user_id = 2),就有访问其他用户信息的风险。
为了防止cookie被篡改,每一个session字符串的尾巴上都带着一个服务器生成的digest。
若用户的content与digest不匹配,服务器就知道这个cookie是伪造的。
digest如何生成
在Rails中,secret保存在 config/initializers/secret_token.rb 文件中。
YourApp::Application.config.secret_key_base = '49d3f3de9ed86c74b94ad6bd0...'
digest生成规则:content + secret token => digest
这个secret token是机密文件,一旦被坏人获取,就可以轻松的伪造cookie(很多菜鸟开源代码时往往犯这个低级错误)。
相关文章推荐
- rails authentication session & cookie
- 抛开cookie使用session-PHP中SESSION不能跨页传递问题的解决办法
- ie与session丢失(新窗口cookie丢失)实测及解决方案
- Application、Session、Cookie、ViewState、Cache、Hidden的区别
- 与Session的亲密接触&彻底掌握Java中Session Token Cookie
- Cookie、session、session+mysql
- cookie/session
- .Net MVC4.0(5) - Session&cookie
- PHP之浅谈cookie和session
- Django | Tornado | Flask 三种web框架的会话跟踪(session|cookie)
- 利用Cookie实现Session跟踪
- session和cookie的区别
- 会话机制详解(Cookie和Session)
- 利用Cookie实现Session跟踪
- session和cookie
- cookie与session
- servlet自学——Cookie和Session
- session和cookie有什么区别
- Cookie和Session
- 深入理解Session与Cookie(一)