Help us understand the problem. What is going on with this article?

RailsアプリではJWTをcookie管理するしかない!!

More than 1 year has passed since last update.

発端

  • JWTログインを、Railsで実装したかった(Gemはjwt/ruby-jwt を利用)
  • ペイロードを基にしたトークン発行まではできた(記事がたくさん書いてある)
  • RFCを見ると、トークンはリクエストヘッダーのAuthorizationBearerスキーマに入れるのがお決まりらしい
  • じゃあどうやって認証サーバから受け取ったトークンをリクエストヘッダに入れるのかな........ん?
  • 入れ方がどこにも書いてない
  • みんなトークン作った後はなぜかcurlで確認だけして文章終了してる
$ curl example.com -H 'Authorization: Bearer <token>'
  • これをアプリでやりたいんだっちゅうに!!
  • なんで誰もWebアプリでの実装方法書いてないの??
  • (某有名プロジェクトに関わっている人)「RailsじゃAuthorizationヘッダーに入れるの無理だよ
  • ?!?!

結論

  • もうでていますが、Railsのロジック上、受け取ったJWTトークンをAuthorizationヘッダに入れてリクエストを飛ばすといったオシャレなことはできません
  • なので、おとなしくCookieに入れてそこで管理しましょう
  • ただセキュリティ対策として、secure属性httponly属性はつけておきましょう!
# bundle install
gem 'jwt'
# lib/json_web_token.rb(config/application.rbでlib配下をautoloadするようにしてください)
class JsonWebToken
  class << self
    def encode(payload, exp = 24.hours.from_now)
      payload[:exp] = exp.to_i
      JWT.encode(payload, secret)
    end

    def decode(token)
      body = JWT.decode(token, secret)[0]
      HashWithIndifferentAccess.new body
    end

    private

    def secret
      Rails.application.secrets.secret_key_base
    end
  end
end
# ApplicationController内でincludeしてください
module SessionHelper
  def current_user
    if (token = cookies[:jwt])
      decoded = JsonWebToken.decode(token)
      @current_user ||= User.find_by(id: decoded[:id])
    end
  rescue JWT::ExpiredSignature
    flash[:danger] = 'Token Expired'
    log_out
    @current_user = nil
    nil
  end

  def logged_in?
    current_user.present?
  end

  # before_actionでログインしていないと入れないページに設定
  def authenticate_user?
    redirect_to login_path unless logged_in?
  end

  def log_in(user)
    payload = { id: user.id }
    token = JsonWebToken.encode(payload)
    # もしhttps通信なら、secure属性もOnにすること
    cookies.permanent[:jwt] = { value: token, httponly: true }
  end

  def log_out
    cookies.delete(:jwt)
  end
end
  • 「そんなことはない(RailsでもAuthorizationヘッダー使えるよ)」というお方、是非とも反論してください!論破してください!お願いします!!
Coolucky
admin-guild
「Webサービスの運営に必要なあらゆる知見」を共有できる場として作られた、運営者のためのコミュニティです。
https://admin-guild.slack.com
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした