问题
I'm using Devise for athentication in my main application and
I have built an API (for a PABX) using "http_basic_authenticate_with" and it's working well when I add before_action :authenticate_user!, except: [:method_name]
to my controller. I'm doing that because except: [:method_name]
will not require a logged user session on Devise and I just want to use basic authenticate for those API controllers.
config/routes.rb
(main application)
scope module: 'api' do
scope module: 'pabx' do
scope '/api/pabx' do
get '/accounts/phone_number/:phone_number', to: 'accounts#phone_number'
end
end
end
controllers/api/pabx/accounts_controller.rb
(main application)
class Api::Pabx::AccountsController < ApplicationController
http_basic_authenticate_with name: 'some_name', password: 'some_password'
before_action :authenticate_user!, except: [:phone_number]
skip_before_filter :verify_authenticity_token
# POST api/pabx/accounts/phone_number.json
def phone_number
...
end
end
The problem is happening when I want to do something similar to that API inside an Engine.
When I try to access the route, Devise seems to not allow to access it without an authentication, even when I'm using before_action :authenticate_user!, except: [:method_name]
.
config/routes.rb
(Myengine)
scope module: 'api' do
scope '/api' do
get '/accounts/phone_number/:phone_number', to: 'accounts#phone_number'
end
end
controllers/api/pabx/accounts_controller.rb
(Myengine)
require_dependency "myengine/application_controller"
module Myengine
class Api::AccountsController < ApplicationController
http_basic_authenticate_with name: 'some_name', password: 'some_password'
before_action :authenticate_user!, except: [:phone_number]
skip_before_filter :verify_authenticity_token
# POST api/pabx/accounts/phone_number.json
def phone_number
...
end
end
This is my the code in the main application
controllers/application_controller.rb
(main application)
class ApplicationController < ActionController::Base # Prevent CSRF attacks by raising an exception.
# For APIs, you may want to use :null_session instead.
protect_from_forgery with: :exception
# Authentication using Devise (DO NOT REMOVE THIS LINE)
before_action :authenticate_user!
end
config/routes.rb
(main application)
authenticate :user do
mount Myengine::Engine, at: '/myengine'
end
When I try to access that method in my Engine, the terminal show me this:
Started POST "/myengine/api/accounts/phone_number.json" for ::1 at 2015-09-17 21:15:31 -0300
Started GET "/users/sign_in" for ::1 at 2015-09-17 21:15:31 -0300
Processing by Devise::SessionsController#new as */*
Rendered users/shared/_links.html.erb (6.3ms)
Rendered users/sessions/new.html.erb within layouts/authentication (29.3ms)
Rendered layouts/elements/_flash_messages.html.erb (2.3ms)
Completed 200 OK in 720ms (Views: 714.4ms | ActiveRecord: 0.0ms)
(If I'm doing something wrong or someone has a better idea, please share here.) (I'm using Devise 3.5.2 with Rails 4.2.0)
Thank you very much for reading my question.
回答1:
I solved the problem, this was simple. Now I'm doing the authentication in my Engine Application Controller, not by routes on my Main Application Controller.
module Myengine
class ApplicationController < ActionController::Base
before_action :authenticate_user!
end
end
I also removed authenticate :user
on my config/routes.rb (main application)
mount Myengine::Engine, at: '/myengine'
That way I'm able to use the following code in any controller
before_action :authenticate_user!, except: [:mypublic_method]
来源:https://stackoverflow.com/questions/32642681/how-can-i-avoid-devise-from-requires-authentication-from-within-an-engine