2017-04-10 30 views
2

私はRails APIをhttp専用のクッキーで認証しているので、CSRF保護が必要です。私が知ることから、Railsコミュニティは、クッキーではなくローカルストレージにjwt authトークンを格納するほうが好まれるようです。これにより、CSRFの必要性が回避されますが、XSSに公開されるため、クッキー+ csrfを使用することになりました。Rails 5 APIモードでCSRFを有効にする方法

ローカルストレージのコミュニティ設定が原因で、CSRF保護がデフォルトで無効になっているようです。私はそれを可能にするために努力しています。ここで私はそれを処理しようとしてる方法です:

クライアント側で
module V1 
    class ApplicationController < ::ApplicationController 
    include Concerns::Authentication 
    include ActionController::RequestForgeryProtection 
    protect_from_forgery 

    protected 

    def handle_unverified_request 
     raise 'Invalid CSRF token' 
    end 

    after_action :set_csrf_cookie 

    def set_csrf_cookie 
     if current_user 
     cookies['X-CSRF-Token'] = form_authenticity_token 
     end 
    end 
    end 
end 

、私はトークンが戻っクッキーでてくることがわかります。私がリクエストをすると、トークンがX-CSRF-Tokenヘッダーにあることもわかります。これまでのところよく見える。

ただし、verified_request?メソッドはfalseを返します。したがってhandle_unverified_requestが呼び出されます。 Railsのコードを実行すると、自分のトークンがrequest.x_csrf_tokenに存在することがわかりますが、sessionと照合したときにトークンの検証に失敗したようです。私がここで思っていることの1つは、セッション管理がAPIモードでデフォルトになっていないことを理解しているので、sessionを正しく動作させるために何かを有効にする必要があるかどうかです。しかし、そのような場合は、sessionオブジェクトにアクセスしようとすると予想されるようになるでしょうし、そうではないので、わかりません。

私はエラーを起こしましたか、それともオンにする必要がある他のミドルウェアがありますか?あるいは、このスキームでCSRFを有効にするためには、別のアプローチが必要ですか?

答えて

4

私は、これが問題を過度に考えていることを実感しました。自分のトークンの値がすでにクッキーであるため、Railsの偽造防止が私にとって何かを行うか、sessionに対して値をチェックする必要はありません。ここで私はそれを解決した方法です:

まず、ベースコントローラはcsrfクッキーを設定します。ログアウトや公開エンドポイントがあれば、これはスキップされます。

module V1 
    class ApplicationController < ::ApplicationController 
    include Concerns::Authentication 
    include ActionController::RequestForgeryProtection 

    after_action :set_csrf_cookie 

    protected 

    def set_csrf_cookie 
     if current_user 
     cookies['X-CSRF-Token'] = form_authenticity_token 
     end 
    end 
    end 
end 

その後、私の認証されたエンドポイントが認証トークンとCSRFトークンをチェックAuthenticatedController継承:

module V1 
    class AuthenticatedController < ApplicationController 
    before_action :authenticate! 

    def authenticate! 
     raise AuthenticationRequired unless current_user && csrf_token_valid? 
    end 

    rescue_from AuthenticationRequired do |e| 
     render json: { message: 'Authentication Required', code: :authentication_required }, status: 403 
    end 

    rescue_from AuthTokenExpired do |e| 
     render json: { message: 'Session Expired', code: :session_expired }, status: 403 
    end 

    private 

    def csrf_token_valid? 
     Rails.env != 'production' || request.headers['X-CSRF-Token'] === cookies['X-CSRF-Token'] 
    end 
    end 
end 

希望これは他の誰かがRailsの5 APIにCSRF +クッキーを使用しようとしているのに役立ちます!

関連する問題