devise 使ってると user_signed_in? とか current_user とか使いますよね?
ブラウザはどのように、現在ログイン中かどうかを認識しているのでしょうか?
解析してみました。
クッキー解析
秘密はクッキーにあります。
以下の手順で、rails でログインしている場合としてない場合でクッキーの違いを見てみましょう。
Chrome でクッキーを確認する方法
https://nomad.office-aship.info/chrome-cookie
以下のように _test_rails_session という項目があります。
これが、ログインを保持している値です。
試しにこの _test_rails_session を削除してリロードすると、ログアウト扱いになります。
このプロジェクトは test_rails というrailsプロジェクト名なので、
名前は _#{railsプロジェクト名}_session という名前になっているようです。
ちなみに、この Value、リロードするたびに変化します。
Qi53lK28PWdWi%2BdR8SVvFnBUGGUV8cKIyFCEP9EkPtIC%2B%2BNO86CYvJ1ALTFaK4MG7iPLXddBweG5qyiCNToHDF1V%2BMF1hZUR%2F4%2BIjJP4BsXSJlFuC2A2Y8jnhmnhpJLjY5NgFjMK7lRhN28wNiTxhrEvJGh1pU5PtivUogd3ik5f2zMZXxWdJ2Zb9WYXFRA43WKqe0g%2B71Yx9QJMRV0wLc00fXpMlmDliR19em%2Bh2wBBfNF%2Buw3j8F9lxVBMqvN55S3NHdQM1Oi8FoQWy5MKXeoFIGccM%2FlJ8LgaZuaYEHWDU%2BGzc4SKVsLqxgi2nteIljbV1fLbN4%2BOpTk2yn5aa0%2BuLLmztBTgOcbA5wufXfy0eFOkqwF%2BdkeZ5GAXKF6UjtkC8ta82aYslNt76MiU%2FrzvuraiU3w%3D–R3iubSvMRrdv6uDT–lu94yoOUEN7cLqYHW6Y1IA%3D%3D
このキーを復号してみます。
以下に掲載のコードで復号できました(rails 6.1.4 で確認済み)
Demystifying cookies in Rails 6 – 2020.11/2
https://binarysolo.chapter24.blog/demystifying-cookies-in-rails-6
以下のファイルを置いて
以下のように実行できます。
ファイル中の cookie の値は、自分の値に書き換えてください。
この時、 Show URL decoded のチェックボックスはオフにしてください。
% bundle exec rails cookie:decode_cookie {"session_id"=>"7bc124c13de60bdc12d810b69aff8ed2", "warden.user.user.key"=>[[2], "$2a$12$lJTRmJqKO3u9iSI28S/6W."], "flash"=>{"discard"=>[], "flashes"=>{"notice"=>"Signed in successfully."}}}
lib/tasks/decode_cookie.rake
# frozen_string_literal: true namespace :cookie do # % bundle exec rails cookie:decode_cookie # 本番では RAILS_ENV=production をつける task decode_cookie: :environment do # Take the following value from your cookie for your web site cookie = 'Qi53lK28PWdWi%2BdR8SVvFnBUGGUV8cKIyFCEP9EkPtIC%2B%2BNO86CYvJ1ALTFaK4MG7iPLXddBweG5qyiCNToHDF1V%2BMF1hZUR%2F4%2BIjJP4BsXSJlFuC2A2Y8jnhmnhpJLjY5NgFjMK7lRhN28wNiTxhrEvJGh1pU5PtivUogd3ik5f2zMZXxWdJ2Zb9WYXFRA43WKqe0g%2B71Yx9QJMRV0wLc00fXpMlmDliR19em%2Bh2wBBfNF%2Buw3j8F9lxVBMqvN55S3NHdQM1Oi8FoQWy5MKXeoFIGccM%2FlJ8LgaZuaYEHWDU%2BGzc4SKVsLqxgi2nteIljbV1fLbN4%2BOpTk2yn5aa0%2BuLLmztBTgOcbA5wufXfy0eFOkqwF%2BdkeZ5GAXKF6UjtkC8ta82aYslNt76MiU%2FrzvuraiU3w%3D--R3iubSvMRrdv6uDT--lu94yoOUEN7cLqYHW6Y1IA%3D%3D' secret_key_base = Rails.application.secret_key_base puts decrypt_session_cookie(cookie, secret_key_base) end private def decrypt_session_cookie(cookie, secret_key_base) unescaped_cookie = CGI::unescape(cookie) data, iv, auth_tag = unescaped_cookie.split("--").map do |v| Base64.strict_decode64(v) end cipher = OpenSSL::Cipher.new("aes-256-gcm") # Compute the encryption key secret = OpenSSL::PKCS5.pbkdf2_hmac_sha1(secret_key_base, "authenticated encrypted cookie", 1000, cipher.key_len) # Setup cipher for decryption and add inputs cipher.decrypt cipher.key = secret cipher.iv = iv cipher.auth_tag = auth_tag cipher.auth_data = "" # Perform decryption cookie_payload = cipher.update(data) cookie_payload << cipher.final cookie_payload = JSON.parse cookie_payload # => {"_rails"=>{"message"=>"InRva2VuIg==", "exp"=>nil, "pur"=>"cookie.remember_token"}} # Decode Base64 encoded stored data decoded_stored_value = Base64.decode64 cookie_payload["_rails"]["message"] stored_value = JSON.parse decoded_stored_value # => "token" end end
生成方法
では、この value の値は、どのように生成されているのでしょうか?
[Rails] deviseのセッション(session)はどのように決められているのか
https://qiita.com/eitches/items/aefa728148cba68f2d6a
Rails6 のセッションの扱いと、クッキーからの復元方法
https://tyfkda.github.io/blog/2020/09/01/rails6-session-cookie.html
wildjcrt/verify_and_decrypt_session_cookie60beta1.rb
https://gist.github.com/wildjcrt/6359713fa770d277927051fdeb30ebbf
pdfrod/decode_session_cookie.rb
https://gist.github.com/pdfrod/9c3b6b6f9aa1dc4726a5
Rails の session を完全に理解した – 2019年07月16日
https://qiita.com/zettaittenani/items/a75f0da8f44cfe0f85c0
ruby-on-rails – Rails 4:Rails 4セッションCookieを復号化する方法(セッションキーとシークレットを指定)
https://base64.work/so/ruby-on-rails/1580567
Rails 3はcookieはbase64デコードで簡単にデコードできる。
Rails 4以降は、AES-256を使用して、アプリのsecret_token_baseに基づくキーでCookieを暗号化します。
How to decode and decrypt cookies in Rails 6
https://www.indiehackers.com/post/how-to-decode-and-decrypt-cookies-in-rails-6-41c420f378
Rails の cookie session をデコードする – 2017-02-25
https://ohbarye.hatenablog.jp/entry/2017/02/25/144008
How to decrypt a Rails 5 session cookie manually?
https://stackoverflow.com/questions/41474176/how-to-decrypt-a-rails-5-session-cookie-manually
今さら聞けないセッションとCookie、ログイン・ログアウト(Rails編) – 2016年1月7日
https://qiita.com/SpicyCoffee/items/de9de9a5427adf81817a
Rails API(サーバサイド)でCookieを作成する方法 – 2022年2月7日
https://nishinatoshiharu.com/rails-serverside-cookies
セッションとかクッキーとかよくわからないので勉強してみた – 2021年6月7日
https://qiita.com/hot_study_man/items/147f8b767b4135fe6fe4
[Rails]sessionとcookies。得意になりたくない? – 2021年04月17日
https://qiita.com/ren0826jam/items/a0d2eb76b4c571a02c2b
Ruby on Rails チュートリアル 第9章 永続的セッション
(cookies remember me 記憶トークン ハッシュ)を解説 – 2021年1月27日
https://qiita.com/bitcoinjpnnet/items/639cbace7cb806379452
Rails6 のセッションの扱いと、クッキーからの復元方法 – 2020-09-01
https://tyfkda.github.io/blog/2020/09/01/rails6-session-cookie.html
RSpec書籍
Everyday Rails – RSpecによるRailsテスト入門
https://leanpub.com/everydayrailsrspec-jp
Rails 7.0に対応した「Everyday Rails – RSpecによるRailsテスト入門」をリリースしました! – 2022-01-17
https://blog.jnito.com/entry/2022/01/17/115109
おすすめRuby書籍
研鑽Rubyプログラミング β版
https://www.lambdanote.com/products/products-polished-ruby-beta
プロを目指す人のためのRuby入門[改訂2版] – 2021/12/2
Ruby on Rails 6 実践ガイド impress top gearシリーズ
現場で使える Ruby on Rails 5速習実践ガイド
Ruby on Rails 6 超入門
コメント