Session trong Rails
Bài đăng này đã không được cập nhật trong 8 năm
Trong công việc của bạn, đôi khi phải làm việc với session
(lúc đăng nhập app, ...), tìm hiểu thêm về session
cũng làm cho việc sử dụng được chủ động hơn.
Thường trong controller
, khi muốn lưu 1 tài khoản đăng nhập, ta thường có câu gán session[:user_id] = current_user.id
, vậy session
là gì và lưu những dữ liệu này ở đâu vậy.
session
đơn gỉan là 1 hash, khi binding.pry
vào controller
ta có thể lấy được các gía trị lưu trong session
.
[1] pry(#<CompaniesController>)> session
=> {"flash"=>{"discard"=>["notice"], "flashes"=>{"notice"=>"ログインしました。"}}, "warden.user.m_employee.key"=>[[1], "$2a$10$6AqCnAGJ2YZZVqInwya16u"], "warden.user.m_employee.session"=>{"last_request_at"=>1466404289}, "_csrf_token"=>"wAGISZWlToFPxzmzgs0xQaFvdYQVW+NJLcZpUHNcu/Y="}
Thử gõ session.class
ta được
[2] pry(#<CompaniesController>)> session.class
=> Rack::Session::Abstract::SessionHash
Có thể lấy options
bằng cách gõ session.options
[16] pry(#<CompaniesController>)> session.options
=> {:path=>"/",
:domain=>nil,
:expire_after=>nil,
:secure=>false,
:httponly=>true,
:defer=>false,
:renew=>false,
:redis_server=>"redis://localhost:6379/0/session",
:expires_in=>10800 seconds,
:servers=>"redis://localhost:6379/0/session"}
:expires_in=>10800 seconds,
là thời gian tồn tại của session
, có thể set lại bằng cách gán lại session[:expires_in]
ta được
[11] pry(#<CompaniesController>)> session.options[:expires_in] = 21600.seconds
=> 20800 seconds
[12] pry(#<CompaniesController>)> session.options
=> {:path=>"/",
:domain=>nil,
:expire_after=>nil,
:secure=>false,
:httponly=>true,
:defer=>false,
:renew=>false,
:redis_server=>"redis://localhost:6379/0/session",
:expires_in=>21600 seconds,
:servers=>"redis://localhost:6379/0/session"}
Nhưng có điểm khác biệt là session
cũng được phân biệt theo id, ta thử gõ session.id
[3] pry(#<CompaniesController>)> session.id
=> "b550dbeee878df09cdaf84cb02a4c209"
Đầu tiên thử tìm hiểu về Rack::Session::Abstract::SessionHash
(http://www.rubydoc.info/github/rack/rack/Rack/Session/Abstract/SessionHash)
SessionHash
là class
thuộc Rack::Session::Abstract
, ta có thể xem class
này tại https://github.com/rack/rack/blob/master/lib/rack/session/abstract/id.rb#L17
Khi ta gõ session.id
thực chất là gọi method
id
của session
def id
return @id if @loaded or instance_variable_defined?(:@id)
@id = @store.send(:extract_session_id, @req)
end
Rails sẽ tạo 1 record
mới khi ta gán session[:current_user_id] = current_user.id
với id
được gán random và được lưu ở cookies
.
Khi lưu dữ liệu trong session
chỉ nên lưu id
của record
, dung lượng cho phép đối với lưu trữ của session
là 4k nên chỉ lưu những thông tin cơ bản.
Mỗi khi có request gửi lên server
, session_id
được trả về
curl -I http://localhost:3000/companies/1 | grep Set-Cookie
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0
Set-Cookie: _session_ id = 0944e88f02029e4e11a016b282e807f4; path=/; HttpOnly
Thử gõ cookies
ta được
[14] pry(#<CompaniesController>)> cookies
=> #<ActionDispatch::Cookies::CookieJar:0x007ff13eb5ace8
@committed=false,
@cookies={"_session_id"=>"b550dbeee878df09cdaf84cb02a4c209"},
@delete_cookies={"request_method"=>{:path=>"/"}},
@host="localhost",
@key_generator=
#<ActiveSupport::CachingKeyGenerator:0x007ff180ccd660
@cache_keys=
#<ThreadSafe::Cache:0x007ff180ccd638
@backend=
{"signed_global_ids64"=>
"s\xE0\xF2\xD1$p\xCAK\x8D\xFA3\xA6>\x9AM\xBAJF\xCC\xDB\x13\xFD\xB2\x81\xAD\x7F\xB1b\x8E\xCE\x12\x1C\vC5\xA2\x8D\\\xFB\x9E\xDFcBv\xD8\xFE\xD7\xBF\x827D\xEE\xB6\x01\vR23*\xC3\x80\x80\xF8\xDB",
"signed cookie64"=>
"#-\x9D\x049\x8A\xBF^\xC1\xB7\xB4\t\xC5rg\x15h\xA8\xF5\xA5\x92>yj\x8D\x83>\xE6\x17F\x1F\fKX/\x00\ad \xD3\xA4\xC9\x1F\xAB\x0F:\r\xF3\xBA5 \x1A\xD5\xC9\x03\xDE\x87hz\xDD\xCFtq\x18"},
@default_proc=nil>,
@key_generator=
#<ActiveSupport::KeyGenerator:0x007ff180ccd6b0
@iterations=1000,
@secret="7635f725c8bddb370d7af1080af8808088045541f6462331180dbf59856054767104f3dd801093ce875e68825388639ac2edf2e110830fbe7aefec3235244ffa">>,
@options=
{:signed_cookie_salt=>"signed cookie",
:encrypted_cookie_salt=>"encrypted cookie",
:encrypted_signed_cookie_salt=>"signed encrypted cookie",
:secret_token=>nil,
:secret_key_base=>"7635f725c8bddb370d7af1080af8808088045541f6462331180dbf59856054767104f3dd801093ce875e68825388639ac2edf2e110830fbe7aefec3235244ffa",
:upgrade_legacy_signed_cookies=>false,
:serializer=>:json,
:digest=>nil},
@secure=false,
@set_cookies={}>
Ta có thể chú ý dòng @cookies={"_session_id"=>"b550dbeee878df09cdaf84cb02a4c209"},
đó chính là id
được gán cho session
Link tham khảo http://www.justinweiss.com/articles/how-rails-sessions-work/
All rights reserved