什么是session
session可以存儲(chǔ)多個(gè)請(qǐng)求需要共享的數(shù)據(jù)。
當(dāng)你對(duì)一個(gè)頁面發(fā)送請(qǐng)求的時(shí)候,rails服務(wù)器的response將會(huì)返回一個(gè)cookie。
Set-Cookie: ...
瀏覽器會(huì)保存這些cookie,直到cookie過期,當(dāng)你每次發(fā)送一個(gè)請(qǐng)求。瀏覽器會(huì)把這個(gè)cookie發(fā)送到服務(wù)器。
Rails中session使用過程
服務(wù)器端
- 當(dāng)使用session[:current_user_id] = 1賦值
- Rails將會(huì)創(chuàng)建一個(gè)session表,產(chǎn)生一個(gè)隨機(jī)的session id。(09497d46978bf6f32265fefb5cc52264)
- Rails將會(huì)存儲(chǔ){current_user_id: 1}(Base64編碼)到session的data屬性中。
- 返回session id,然后將session id存到cookie里發(fā)送到瀏覽器(如果要將session存儲(chǔ)到cookie中,rails會(huì)將data一并存儲(chǔ)到cookie中去)
瀏覽器
- 當(dāng)瀏覽器下次發(fā)送請(qǐng)求到服務(wù)器的時(shí)候會(huì)帶上這個(gè)cookie,也就是session id
- Rails會(huì)根據(jù)session id去session表中查詢出對(duì)應(yīng)的session值
- 從記錄的data屬性中返回current_user_id
在Rails中默認(rèn)使用Cookie保存Session信息。配置文件在config/initializers/session_store.rb中。在文件config/secrets.yml中設(shè)置了一組secret_key_base用來加密需要保護(hù)的Cookie信息,修改這個(gè)數(shù)會(huì)讓存在用戶瀏覽器的Cookie Session失效??梢杂眠@個(gè)來強(qiáng)制重新登錄。
也可以在這個(gè)文件中添加第三方的key或者token??梢酝ㄟ^Rails.application.secrets.some_api_key訪問到設(shè)置的數(shù)據(jù)。
使用memcached
可以在config/environments/production中設(shè)置
config.cache_store = :mem_cache_store
使用數(shù)據(jù)庫(kù)
Rails session解密
- 在rails中設(shè)置session
session[:current_user_id] = 12
session[:user] = "2b"
- 在瀏覽器查看

Paste_Image.png
- 解密cookie
require 'rubygems'
require 'cgi'
require 'active_support'
require 'action_controller'
def decrypt_session_cookie(cookie, key)
cookie = CGI::unescape(cookie)
# Default values for Rails 4 apps
key_iter_num = 1000
key_size = 64
salt = "encrypted cookie"
signed_salt = "signed encrypted cookie"
key_generator = ActiveSupport::KeyGenerator.new(key, iterations: key_iter_num)
secret = key_generator.generate_key(salt)
sign_secret = key_generator.generate_key(signed_salt)
encryptor = ActiveSupport::MessageEncryptor.new(secret, sign_secret, serializer: ActiveSupport::MessageEncryptor::NullSerializer)
# puts MarShal.load(encryptor.decrypt_and_verify(cookie))
puts encryptor.decrypt_and_verify(cookie)
end
#
cookie = 'cTI0N2R6SVc5VlFqRGtjalZobXdsWmdDeVVaajlIU3JpU052T3ZVVkp1ZEdXQ29YSGRNcGxuYmJmd2IzQUNFL0hRNGgzY0ZWOUtxR2FJU2NWc3FSZTdoU0hWQlZ6TmRjazNHN0RXV2d3N1VyeTZkSXFzaTZ0K0g1a1JpaENwTGMtLTdTUUlpeFd2ZTNvWWVYRHVvNFdPUEE9PQ%3D%3D--98bbeff308c62d37472caa84ea47af49a67b50dd'
# key是rails中secrets.yml中設(shè)置的secret_key_base
key = '9ef39555bee9dc9d2a8aa1b519ba4221ef722ed9bf248e789946cf317f5ff087d3fde1eb8c60eca6fe8b3b851c9cde2f7c318506e6b416f6938aa8203d4625e5'
decrypt_session_cookie(cookie, key)
- 解密后的數(shù)據(jù)

Paste_Image.png
通過解密完全得到原始數(shù)據(jù),所以在session中千萬不要存儲(chǔ)重要的數(shù)據(jù)。也千萬不要將key泄漏出去。