Closed unDeveloper closed 8 years ago
Having the same issue. Any progress?
I'm still doing some testing, but it seems to be resolved modifying
before_action :authenticate_user!
to
before_filter :authenticate_user!, except: [:new, :create]
If something new comes to surface I'll let you know
Regards!
Having same problem, did you find a solution ?
I'm having the same problem. I can login fine and even replay a few 'validate_token' requests, but at some point it will fail and give me 401 unauthorized.
Can you post your configuration? How are you handle the request headers and response headers? Did you had any errors during those requests?
I'm using ng-token-auth to do all of the communication with the rails API. My configs are all default for now, following are the files I've changed:
application_controller.rb
class ApplicationController < ActionController::Base
# Prevent CSRF attacks by using :null_session
protect_from_forgery with: :null_session
include DeviseTokenAuth::Concerns::SetUserByToken
...
user.rb
class User < ActiveRecord::Base
# Include default devise modules.
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable,
:confirmable, :omniauthable
include DeviseTokenAuth::Concerns::User
...
Is there any other file that could be interfering with that?
Thank you for the impressively fast response 😃
Well i have a little time before i go to sleep...
Back to the point... I'm assuming you've have installed and configured rack/cors for crossite requests when you configure devise_token_auth?
Yes! This is what my application.rb looks like:
require File.expand_path('../boot', __FILE__)
require 'rails/all'
# Require the gems listed in Gemfile, including any gems
# you've limited to :test, :development, or :production.
Bundler.require(*Rails.groups)
module RailsSports2
class Application < Rails::Application
# Settings in config/environments/* take precedence over those specified here.
# Application configuration should go into files in config/initializers
# -- all .rb files in that directory are automatically loaded.
# Set Time.zone default to the specified zone and make Active Record auto-convert to this zone.
# Run "rake -D time" for a list of tasks for finding time zone names. Default is UTC.
# config.time_zone = 'Central Time (US & Canada)'
# The default locale is :en and all translations from config/locales/*.rb,yml are auto loaded.
# config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}').to_s]
# config.i18n.default_locale = :de
# Do not swallow errors in after_commit/after_rollback callbacks.
config.active_record.raise_in_transactional_callbacks = true
config.middleware.use config.session_store, config.session_options
config.middleware.use Rack::MethodOverride
config.middleware.use ActionDispatch::Cookies
config.middleware.use ActionDispatch::Session::CookieStore
config.middleware.use ActionDispatch::Flash
config.autoload_paths += %W( #{config.root}/lib )
config.middleware.use Rack::Cors do
allow do
origins '*'
resource '*',
:headers => :any,
:expose => ['access-token', 'expiry', 'token-type', 'uid', 'client'],
:methods => [:get, :post, :options, :delete, :put]
end
end
end
end
Try this in your application_controller.rb
before_filter :add_allow_credentials_headers
skip_before_filter :verify_authenticity_token
before_filter :cors_preflight_check
after_filter :cors_set_access_control_headers
before_filter :authenticate_user!, except: [:new, :create]
def cors_set_access_control_headers
headers['Access-Control-Allow-Origin'] = '*'
headers['Access-Control-Allow-Methods'] = 'POST, GET, PUT, DELETE, OPTIONS'
headers['Access-Control-Allow-Headers'] = 'Origin, Content-Type, Accept, Authorization, Token'
headers['Access-Control-Max-Age'] = '1728000'
end
def cors_preflight_check
if request.method == 'OPTIONS'
headers['Access-Control-Allow-Origin'] = '*'
headers['Access-Control-Allow-Methods'] = 'POST, GET, PUT, DELETE, OPTIONS'
headers['Access-Control-Allow-Headers'] = 'X-Requested-With, X-Prototype-Version, Token'
headers['Access-Control-Max-Age'] = '1728000'
render :text => '', :content_type => 'text/plain'
end
end
def add_allow_credentials_headers
# https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS#section_5
#
# Because we want our front-end to send cookies to allow the API to be authenticated
# (using 'withCredentials' in the XMLHttpRequest), we need to add some headers so
# the browser will not reject the response
response.headers['Access-Control-Allow-Origin'] = request.headers['Origin'] || '*'
response.headers['Access-Control-Allow-Credentials'] = 'true'
end
This seems to extend the span between login into the application and getting the 401, but doesn't seem to fix the problem yet 😢
Started POST "/api/v1/tips/byaddress" for ::1 at 2016-09-04 23:24:23 -0700
Processing by TipsController#list_by_address as HTML
User Load (0.5ms) SELECT "users".* FROM "users" WHERE "users"."uid" = $1 LIMIT 1 [["uid", <user_id>]]
Filter chain halted as :authenticate_user! rendered or redirected
Completed 401 Unauthorized in 62ms (Views: 0.2ms | ActiveRecord: 0.5ms)
Looking at the query, seems to get the wrong param, or you changed it when you post it? Seems to be received an user_id instead of the user id.
SELECT "users".* FROM "users" WHERE "users"."uid" = $1 LIMIT 1 [["uid", <user_id>]]
My bad.
Adding "before_filter :authenticate_user!, except: [:new, :create]" to the application_controller.rb wouldn't let me login, returning me:
{"errors":["Authorized users only."]}
So I moved it to the only controller that I actually need it for now, but didn't add the "except: [:new, :create]" part, because I'm not using those methods there and didn't think it would make a difference. Adding that seems to have fixed the issue!
Thank you for your help @unDeveloper !! I really appreciate it 😃
keep it up or check out my repo here devise token auth
The problem is before_action :authenticate_user!
in ApplicationController
.
Why? See the devise_token_auth's inheritance structure.
DeviseTokenAuth::SessionsControlle < DeviseTokenAuth::ApplicationController
DeviseTokenAuth::ApplicationController < DeviseController
DeviseController < ApplicationController
Because of the inheritance structure, all actions like sessions#create in devise_token_auth call authenticate_user!
. When we request sign_in, our rails app check access-token that actually not exist s in header and it returns Filter chain halted as :authenticate_user! rendered or redirected
. The before action should not be called before sessions#create
Solutions
before :authenticate_user!
in only controller that you actually needconfig.parent_controller = "ActionController::Base"
in config/devise.rb
I'm developing a json API with rails, using rails-api gem, devise_token_auth and angularjs. Using the standard configuration all seems to be ok until I active the line of:
before_action :authenticate_user!
From that point my app only show me the next error: Filter chain halted as :authenticate_user! rendered or redirected
I was reading that this seem caused about a missing header on the request, but i couldn't figure out what i am doing wrong.
This is my configuration until now: Gemfile
application.rb
application_controller.rb
devise_token_auth.rb
devise.rb
My angular app is literaly a copy and paste of the examples using in the repo for ng-token-auth, with index.html making registration of users and index2.html doing the login request.
This is the link for the application repo that i'm using for testing: APITest
Hope you can help me!
Thanks in advance =D