I'm trying to implement token-based API and saw these snippets by google
However, it's hard to understand the meaning by the literal meaning.
Any direction or basic knowledge about this, Thanks ~~
class ApplicationController < ActionController::Base
protect_from_forgery with: :exception, if: Proc.new { |c| c.request.format != 'application/json' }
protect_from_forgery with: :null_session, if: Proc.new { |c| c.request.format == 'application/json' }
end
Rails's document about null_session is here http://api.rubyonrails.org/classes/ActionController/RequestForgeryProtection/ProtectionMethods/NullSession.html#method-i-handle_unverified_request, if you check the source code of it's handle_unverified_request method:
def handle_unverified_request
request = @controller.request
request.session = NullSessionHash.new(request.env)
request.env['action_dispatch.request.flash_hash'] = nil
request.env['rack.session.options'] = { skip: true }
request.env['action_dispatch.cookies'] = NullCookieJar.build(request)
end
that means if the request dose't get through the verify_authenticity_token ,then rails will not fetch the session by cookie data, but create a new session for this request. And that session is a instance of NullSessionHash, so "null_session".
I had this concern when working on a Rails 6 API only application.
By default, Rails applies Cross-Site Request Forgery (CSRF) protection to all controllers that subclass from ApplicationController using the following line:
protect_from_forgery with: :exception
But are there instances where you’d want to respond differently, or even ignore CSRF protection altogether? The answer, of course, is “yes”.
If your project or a portion of your project uses an alternative method for authentication such as API tokens or any other “stateless” authentication, then you can safely remove the protect_from_forgery
line from whatever base class those controllers inherit.
On the other hand, if your project uses stateful authentication and APIs, such as those projects with lots of AJAX requests, it can be advantageous to use :null_session
with protect_from_forgery
like so:
protect_from_forgery with: :null_session
That means the user won’t be logged in anymore for that action and can’t perform the change (if the action requires a signed-in user). However, after the action, the session values will be back and the session ID will be the same, so the user will be logged in.
Rather than throwing an exception, which your JavaScript may not be able to handle, it instead sets the session value to nil
for the duration of the action. By doing this, any authorization or action scoped to the current user will result in errors that your JavaScript can more easily work with.
So, if you're working on a Rails API only application, you can use this to protect against Cross-Site Request Forgery (CSRF) attacks. This suffices for both cases when either of them arises:
class ApplicationController < ActionController::API
include ActionController::RequestForgeryProtection
if Proc.new { |c| c.request.format != 'application/json' }
protect_from_forgery with: :exception
end
if Proc.new { |c| c.request.format == 'application/json' }
protect_from_forgery with: :null_session
end
end
This implements protect_from_forgery with: :exception
when your requests are not of the application/json
format, and protect_from_forgery with: :null_session
when your requests are of the application/json
format.
Note: protect_from_forgery
is a class method included in ActionController::RequestForgeryProtection
, which is why include ActionController::RequestForgeryProtection
was included.
Resources:
That's all.
I hope this helps
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With