Comments (15)
Hi @Rotimi,
The answer is yes to both questions:
- As you correctly noticed, the CSRF protection should be disabled for an API (see the issue 37 for references). Now, once the CSRF protection is disabled, it's very important to disable this gem fallback to Devise (as explained in #49). That's the whole point of the
fallback_to_devise: false
option (documented in the Installation section of theREADME
). - You're also correct about the second part: since there is no fallback if token authentication fails, you must restrict access to your data when
current_user
is missing. You could also use therequire_authentication_of_entity!
method (a good option IMO) written by @donbobka in this commit (take a look at #61 for context). The current release doesn't include it, and you would have to add it by yourself, but you could of course find help here if necessary.
from simple_token_authentication.
@Rotimi, IMO the best way of gem usage for api following:
protect_from_forgery with: :null_session
- It isn't a disabling of CSRF protection, it's another method of protection:
:null_session
- Provides an empty session during every requestconfig/initializers/simple_token_authentication.rb
without modification- Example:
# /app/controller/api/base_controller.rb
class API::BaseController < ActionController::Base
protect_from_forgery with: :null_session # CSRF protection for API
end
# /app/controller/api/v1/post_controller.rb
class API::V1::PostController < API::BaseController
acts_as_token_authentication_handler_for User, only: [:new]
def index
# ... Accessible for unauthenticated users ...
end
def show
# ... Accessible for unauthenticated users ...
end
def new
# ... Only for authenticated users...
# If current_user is missing, devise throw error with status code 401
end
end
In this way you have a CSRF protection and devise will handle cases when current_user is missing
from simple_token_authentication.
Note @Rotimi: @donbobka is right, protect_from_forgery with: :null_session
doesn't disable CSRF protection, that's why the skip_before_action :verify_authenticity_token, if: :json_request
instruction is necessary (Rails request forgery protection documentation).
from simple_token_authentication.
For reference: #45
from simple_token_authentication.
IMO this documentation(Rails request forgery protection documentation) is obsolete. Because without verify_authenticity_token
call protect_from_forgery with: :null_session
do nothing.
from simple_token_authentication.
I may be wrong, but I think that's the point. AFAIK the CSRF protection does not make sense for API (I have previously references this post about that), that's why we disable it.
from simple_token_authentication.
I made PR to rails(rails/rails#15608) about this obsolete documentation. Let's look what will say rails maintainers.
My quote from this PR, why skip_before_action :verify_authenticity_token
should be deleted:
:null_session was discussed in #5326. Quote from there:
null_session is another change we'd discussed, instead of resetting the session it should just assign the cookie and session objects to values which return null for everything and then send no Set-Cookie headers in the response.
Look at method
handle_unverified_request
In case you call
skip_before_action :verify_authenticity_token
,handle_unverified_request
method ofNullSession
class wouldn't be called. It's mean that session variable will be real session and all data populated to session will be stored for subsequent requests. That's means that api will be vulnerable for CSRF attacks.But if you delete
skip_before_action :verify_authenticity_token
line. session will be NullSessionHash and all data populated to session will be lost for subsequent requests
from simple_token_authentication.
All the ideas being made @gonzalo-bulnes @donbobka are useful but it seems they highly depend on the use case. For a non-browser client it seems disabling csrf is standard but it turns out that it is not advised when a browser is consuming the json api. See: this and this
So I believe the options for a client agnostic api are:
-
As @gonzalo-bulnes has mentioned the simplest way would be to allow csrf and the devise fallback. Then send the csrf token with every json request from the browser and mobile client. Extracting the csrf token from rails/devise on something like android/ios requires some work.
-
Disable csrf protection and disable the devise fallback. Implement access restriction when token auth fails or current_user is missing. And finally disable cookie session storage and devise sending cookies to the clients with
config.skip_session_storage
. Might be code leading to vulnerabilities. -
Follow @donbobka steps that keep csrf and devise fallback while using
protect_from_forgery with: :null_session
but not usingskip_before_action :verify_authenticity_token, if: :json_request
. This way rails will destroy a session without a csrf token without raising an exception. See: this
I will probably go with option 3 since it preserves the simple_token_authentication and devise gems especially with their community vetting.
Thanks for the help and guidance!
PS: With this method is there a problem with devise sending session cookies on registration and login or when devise actually comes into play when current_user
is missing @donbobka ?
from simple_token_authentication.
This way rails will destroy a session without a csrf token without raising an exception.
In this way rails works if you use protect_from_forgery with: :reset_session
. As i mentioned before :null_session
keeps your session and cookies untouched, at the same time for your api requests (all actions under protect_from_forgery with: :null_session
) it provides an empty session (here) and empty cookies (here) and skip session update step (here).
PS: With this method is there a problem with devise sending session cookies on registration and login or when devise actually comes into play when current_user is missing @donbobka ?
Due to :null_session
provides to your request empty session, devise have to authorize user with email and token every request. If pair email/token is invalid or absent, current_user would be missing, therefore authenticate_user!
method of devise
throws a error.
from simple_token_authentication.
from simple_token_authentication.
This configuration is correct for for Grape gem?
My application run for http and api mode.
Rails 4.2.4 Devise 3.5.6, simple_token_authentication 1.12.0, grape 0.14.0
config/initializers/simple_token_authentication.rb without modification
My User model:
class User < ActiveRecord::Base
acts_as_token_authenticatable
devise :database_authenticatable,
:recoverable,
:timeoutable,
:registerable,
:confirmable,
:trackable,
:validatable,
:lockable,
:password_expirable,
:secure_validatable,
:password_archivable,
:expirable,
:authentication_keys => [:email]
#gem 'devise_security_extension'
#devise :password_expirable,
# :secure_validatable,
# :password_archivable,
# :session_limitable,
# :expirable
....
end
class ApplicationController < ActionController::Base
protect_from_forgery with: :exception
protect_from_forgery with: :null_session, :if => Proc.new { |c| c.request.format == 'application/json' }
acts_as_token_authentication_handler_for User, fallback: :none
....
end
and routes.rb
mount API::Base, at: "/"
end
inside app/controllers/api/v1/certificates.rb
module API
module V1
class Certificates < Grape::API
include API::V1::Defaults
#include Devise::Controllers::Helpers
acts_as_token_authentication_handler_for User
resource :certificates do
desc "Return all certificates"
get "", root: :certificates do
authenticate_user!
Certificate.all
end
end
end
end
end
end
..and WEBrick (when run) show error:
/home/xxxxxxx/my_app/app/controllers/api/v1/certificates.rb:8:in `<class:Certificates>': undefined method `acts_as_token_authentication_handler_for' for API::V1::Certificates:Class (NoMethodError)
if uncomment
include Devise::Controllers::Helpers
...this error show to :(
What is wrong?
from simple_token_authentication.
Hello @BSorbus,
The Grape support is work in progress (and I need help with it from someone familiar with Grape!) The intent is described in the wiki, progress is coordinated from #138 (there are intructions there to use the experimental code), and the current bottleneck is described in #194.
I suggest you start from #194, as it contains links to the most relevant comments in #138. Please let me know in #138 if you experiment difficulties using the experimental branch, and if you are able to suggest how the Simple Token Authentication methods / callbacks should be distributed between Grape::API
and Grape::Endpoint
so the usage feels convenient to Grape users.
from simple_token_authentication.
Thanks for the information.
I wish ( myself too :) ) the expeditious completion of this adapter :)
from simple_token_authentication.
The auth_token gets created in the database when we try to create the user, how should we stop this to generate auth_token only at login POST call.
from simple_token_authentication.
Hello @ratneshnavlakhe,
Can you open a new issue with your question please?
You can just copy your comment in a new issue, give it a title and I'll reply to you there!
Keeping topics separate makes easier for anyone having the same question to find yours.
Thank you!
from simple_token_authentication.
Related Issues (20)
- Is that gem work with API? HOT 4
- Mongoid does support Rails 6 now/soon HOT 3
- uninitialized constant SimpleTokenAuthentication::Adapters HOT 5
- Gem doesn't protect data?
- separate registration and signin so no token is received by client when registering
- how to auth 2 different models with same alias ?
- acts_as_token_authenticatable causes a DEPRECATION WARNING
- Q: How to do not require user_email? HOT 1
- Getting 401 unauthorized Error
- Where should I store the token on the frontend? HOT 3
- Entering fallback! with token_correct? set to true HOT 1
- 406 Errors on Authentication Test
- The mongoid range of supported versions needs review
- Discussions are set up! HOT 1
- Identify support requests, feature requests in issues and pull requests HOT 1
- Update the contributing guidelines to mention Discussions etc.
- Add (actual) example of maintenance trade-off for discussion HOT 1
- split responsibilities of acts_as_token_authentication_handler_for method HOT 1
- Rails 7 support? HOT 30
- Can we use JWT as a user token?
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from simple_token_authentication.