Open casertap opened 9 years ago
I'm having a hard time understanding this issue. Can you please elaborate? For example, what do you mean by "stateful"?
Also, have you read this section of the README?
Ok I will try to be more clear. I actually have an application that use Devise to loggin/signin etc... So when I currently loggin, a new current_user is created and then I keep this user until he logout.
We are migrating page after page to angularJS so I was wondering if it is possible to have devise_token_auth on pages with angular and my standard Devise for my old pages. The thing is that I only want an unique way to loggin.
@casertap Yes, you can have normal (cookie) based devise for your legacy pages and, as you migrate to angular, use DeviseTokenAuth for your new angular pages. The way I'm handling it now is having the DeviseTokenAuth::Concerns::SetUserByToken
check for a warden.user
in session before checking the token headers. For old pages -- the user is authenticated via devise. For new angular pages the user is authenticated via DeviseTokenAuth (via ng-token-auth).
The way I'm handling it now is having the DeviseTokenAuth::Concerns::SetUserByToken check for a warden.user in session before checking the token headers.
@nickL - that sounds like a good strategy. Should we incorporate this behavior into the gem?
@lynndylanhurley: Yeah, I think it may be useful. Here's a quick snippet. Let me know if I'm on the right track and I'll clean it up more and submit a PR:
def set_user_by_token(mapping=nil)
# determine target authentication class
rc = resource_class(mapping)
# no default user defined
return unless rc
# user has already been found and authenticated
return @resource if @resource and @resource.class == rc
# parse header for values necessary for authentication
uid = request.headers['uid']
@token = request.headers['access-token']
@client_id = request.headers['client']
@client_id ||= 'default'
#**** Money line here... looking for user via warden first..****
#*********************************************************************
#
if warden.user
user = warden.user
user.provider ||= "email"
user.uid ||= user.email
user.save if user.changed?
sign_in(:user, user, store: false, bypass: true)
return @resource = user
else
return false unless @token
# client_id isn't required, set to 'default' if absent
# mitigate timing attacks by finding by uid instead of auth token
user = uid && rc.find_by_uid(uid)
Crap, that user.provider=
& user.uid
stuff is specific to our implementation, worth ignoring.
@nickL - looks good to me! If you have time to send a PR I'll merge ASAP.
Cool! I'll whip up a PR and add some tests. Thanks dude!
On Wed, Mar 25, 2015 at 12:26 PM -0700, "Lynn Dylan Hurley" notifications@github.com wrote:
@nickL - looks good to me! If you have time to send a PR I'll merge ASAP.
— Reply to this email directly or view it on GitHub.
@nickL it is an awesome solution thanks a lot. I can't wait for this feature to be included in the gem.
I'm not sure if this is the best issue to comment on or if I should make a new one.
I am using ActiveAdmin together with this gem and have noticed that /admin/logout (which results in "active_admin/devise/sessions#destroy" and presumably maps to the normal Devise sign-out) sets "current_user" to nil, but /auth/sign_out does not. This is leading to some inconsistencies where I can sign out on using /auth/sign_out, but can directly go to my AA page at /admin and still be signed in...
There's now documentation in the Can I use this gem alongside standard Devise?
section of the README. Doesn't this solve this issue?
The documentation on this is very difficult to piece together. I’d try to rewrite it but I haven’t gotten my standard Devise actions working again since adding the gem.
From the readme:
Yes! But you will need to enable the support use separate routes for standard Devise. So do something like this:
config/initializers/devise_token_auth.rb
DeviseTokenAuth.setup do |config| # enable_standard_devise_support = false end
Why is the config line commented out? Shouldn’t it be
config.enable_standard_devise_support = true
intead of
# enable_standard_devise_support = false
Can someone help me? What is the solution to this bug? I've been crawling around the internet.
I have the issue with the latest version. Original devise seems not to be working after adding this gem
For me, it gives me an error here:
def set_user_by_token(mapping=nil)
# determine target authentication class
rc = resource_class(mapping)
The error message is:
wrong number of arguments (given 1, expected 0)
Apparently, Devise has changed that resource_class no longer accepts an argument? Is that is what is causing this to fail? Because right now, it never gets to the line if DeviseTokenAuth.enable_standard_devise_support
It seems like a lot of people are having the same issue here, dating back to 2015 and we are now in January 2017. I think what happened is that the Devise gem made updates that adversely influenced the behavior of this gem. Since this gem is no longer maintained, this gem can no longer work in conjunction with Devise (for the web). I assume the solution now is to migrate to this gem: https://github.com/gonzalo-bulnes/simple_token_authentication
@JohnMerlino2 Is it true what you said: "Since this gem is no longer maintained, this gem can no longer work in conjunction with Devise (for the web)"?
Because this repo seems active and last commit was a month ago.
I was having the same issue where i need to sign a user into both devise
and devise-token-auth
. First i set up my login page to be a standard Devise
login page. I than extended Devise::SessionController#create:
def create
super do |user|
session[:token] = true
end
end
In the ApplicationController I added:
before_filter :set_token
def set_token
if session[:token] && user_signed_in?
newAuth = current_user.create_new_auth_token
response.headers.merge!(newAuth)
@auth_token = newAuth
session.delete(:token)
else
@auth_token = false
end
end
Finally in views/layouts/application.html.haml i added:
- if @auth_token
:coffee
myApp.controller 'cookieController', ($scope, $resource, $http, $mdDialog, $auth, ipCookie ) ->
ipCookie('auth_headers', "{\"access-token\": \"#{@auth_token['access-token']}\",\"token-type\": \"Bearer\",\"client\": \"#{@auth_token['client']}\",\"expiry\": \"#{@auth_token['expiry']}\",\"uid\": \"#{@auth_token['uid']}\"}", {path: "/",expires: 9999,expirationUnit: 'days',secure: false})
ipCookie('currentConfigName', 'default', {path: "/",expires: 9999,expirationUnit: 'days',secure: false})
%div{'ng-controller'=>'cookieController'}
I realize that this is a little hacky and that my code could be a lot cleaner; that said i wanted to share it with you as a possible solution for people looking to authenticate with both devise
and devise-toke-auth
.
I was working in a similar case where I needed to use both, devise+devise_token_auth in a spree application. I was trying to implement authentication for spree_api and migrating the authentication of spree system(Full Stack App) to devise. I found a way to do it and it's very simple.It's not a common thing in rails but it works great. The idea is to have a main application_controller.rb in your application and particular application_controllers for each section. In my case one for admin system in spree and the other one for API.
#controllers/api/v1/application_controller.rb
module Api
module V1
class ApplicationController < ApplicationController
skip_before_action :verify_authenticity_token
include DeviseTokenAuth::Concerns::SetUserByToken
end
end
end
In the API controller I included the regular DeviseTokenAuth concern to manage auth in the app that controls this application_controller.rb. Note that this controller inherits from the main application_controller.
#controllers/admin/application_controller.rb
module Admin
class ApplicationController < ApplicationController
before_action :authenticate_user!
end
end
This controller is, well, natural behavior of devise. I just needed to add the before action method. We just need the base application_controller ;)
class ApplicationController < ActionController::Base
protect_from_forgery with: :exception, if: :verify_api
def verify_api
params[:controller].split('/')[0] != 'devise_token_auth'
end
end
Our main application_controller.rb looks like this. You need to keep the CSRF token protection but you can avoid it when an API request arrive. The idea is to redirect each flow in your application. the ones that belongs to your full-stack app and the other ones that belongs to your API. Well, in this case to my API :smile: This scenario was tested using devise (4.2.0) and devise_token_auth (0.1.40). I hope I can help someone with this example. Regards
I've created a PR to add @jotolo suggestion to the FAQ: https://github.com/lynndylanhurley/devise_token_auth/pull/1175
I have a lot of trouble to set up my application with both devise and devise_token_auth. We are slowly migrating from a rails server-side rendering to an angularjs application. The problem is that I want to have a way to log in and have part of my website with angular and part without angular (yet). It seems that with devise_token_auth the current_user is not statefull, that is a problem for me because I need to log in ones and then I just need to check if current_user exists. At least I need to do that until the migration is complete and I can totally switch to a token auth. Do you have an idea on how to solve my problem?