I am running a Sinatra
app within an EventMachine.run
loop and in my ws.onopen
method I wish to check the handshake
header's cookie to ensure that the incoming request is coming from a registered user of my webapp.
My Sinatra
app includes the following:
use Rack::Session::Cookie, :key => COOKIE_KEY,
:path => '/',
:expire_after => 2592000, #30 days
:secret => COOKIE_SECRET
and my ws.onopen
method looks like this (trimmed)
ws.onopen { |handshake|
cookie, bakesale = handshake.headers['Cookie'].split('=')
rack_cookie = Rack::Session::Cookie.new(MyApp, {
:key => COOKIE_KEY,
:path => '/',
:expire_after => 2592000, #30 days
:secret => COOKIE_SECRET
})
decoded = rack_cookie.coder.decode(bakesale)
puts "decoded: #{decoded}"
}
The value of cookie
matches my COOKIE_KEY
just fine, however the value of decoded
is nil
How should I decode the incoming cookie data?
-- some time later --
I've changed the above slightly to
ws.onopen { |handshake|
cookie, bakesale = handshake.headers['Cookie'].split('=')
rack_cookie = Rack::Session::Cookie.new(MyApp, {
:key => COOKIE_KEY,
:path => '/',
:expire_after => 2592000, #30 days
:secret => COOKIE_SECRET,
:coder => Rack::Session::Cookie::Base64.new
})
puts rack_cookie.coder.decode(bakesale)
}
and that outputs
?q?[?????ov??????to?Z???294cb6e2b95e9?##v3???#c&F3#SC?CSC#CSs?c3sSCCs?cCm;FI"__FLASH__;F{I" user;FU:Moped::BSO?㣤?&?V7D?B!
which looks like it needs marshalling.
However Marshal.load (rack_cookie.coder.decode(bakesale))
throws an exception, saying dump format error for symbol(0x10)
-- and even more time later --
I also tried rack_cookie.coder.decode(bakesale.split('--').first)
which resulted in
??H?d????=?d:ETI"E7ce599b294cb6e2b95e9?##v3???#c&F3#SC?CSC#CSs?c3sSCCs?cCm;FI"__FLASH__;F{I" user;FU:Moped::BSO?㣤?&?V7D?B!
So as you can see, there is a minor difference, but either way I need to somehow turn that into a valid hash.
Marshal.load(rack_cookie.coder.decode(bakesale.split('--').first)) still results in dump format error for symbol(0x10)
either way.
So I feel I'm closer, but no cigar as yet.
The answer is to use Rack::Utils.unencode
.
I now have this working
Marshal.load(rack_cookie.coder.decode(Rack::Utils.unescape(bakesale.split('--').first)))
decodes perfectly to the hash I need, allowing me to extract the user ID. W00t!
Many thanks to User spastorino over at https://github.com/rack/rack/issues/551 for pointing me in the right direction.
来源:https://stackoverflow.com/questions/16312024/how-to-decode-a-cookie-from-the-header-of-a-websocket-connection-handshake-rub