I've followed the Devise wiki to switch the login route from /users/sign_in to /login. My routes file looks like this:
devise_for :users, :controllers => { :omniauth_callbacks => "users/omniauth_callbacks" }
devise_scope :user do
get '/login' , :to => 'devise/sessions#new' , :as => :login
delete '/logout', :to => 'devise/sessions#destroy', :as => :logout
end
and my user model has this
class User < ActiveRecord::Base
devise :omniauthable, :database_authenticatable
end
I have a common scenario where a user is logged out, tries to access a restricted page, and then redirected to log himself in.
However, when that user is redirected, devise sends them to /users/sign_in path instead of /login.
The only way I could make the redirection to the /login url work is by adding this to the top of my routes.rb:
match "/users/sign_in" => redirect('/login')
which adds a redirect to my application, which in turn messes up tests - whenever I do something like this:
current_url.should == login_path
I get an error saying the expected path was "/login" and the actual was "/users/sign_in".
Did I miss something here - what's an elegant way to work around it? thanks.
side note
I only use :omniauthable to authenticate, but I added :database_authenticatable to devise configuration to force it to go to a dedicated login page.
Otherwise, devise always directs to the root path, so it would seem. If you know of a better way to do that, please - chime in.
Related
In a rails 3 project with devise, how puts the login page /users/sign_in in the root path.
my application is placed in
URL like: http://host/my_app
I am using devise for authentication
when i call the URL, the URL should automatically redirect to
http://host/my_app/users/sign_in
but
my application is forwarding to
http://host/users/sign_in
how to redirect the devise authentication to http://host/my_app/users/sign_in?
Thanks in advance
The devise docs talk about how to update the sign-in and sign-out routes. You should be able to prepend my_app using the same procedure documented.
you can skip default routes, check it out here
# config/routes.rb
devise_for :users, :skip => [:sessions]
as :user do
get 'my_app/users/sign_in' => 'devise/sessions#new', :as => :new_user_session
post 'my_app/users/sign_in' => 'devise/sessions#create', :as => :user_session
delete 'my_app/users/signout' => 'devise/sessions#destroy', :as => :destroy_user_session
end
After a user signs in, I want them to be redirected to /users/2 or users/44, like a normal resource. (That way an admin can easily view any user's profile page just by knowing their id.)
I have no idea what is going on in my routes file. When a user logs in, I can see in the logs that it authenticates properly, and that my application_controller's after_sign_in_path_for is called.
But this is the error that I am getting when I try to redirect_to user_path(current_user).
No route matches {:action=>"show", :controller=>"users", :user_id=>11}
My config/routes.rb
devise_for :users, :path_names => {:sign_in => 'signin', :sign_out => 'signout', :sign_up => 'signup' }
devise_scope :user do
get "signin", :to => "devise/sessions#new"
get "signout", :to => "devise/sessions#destroy", via: :delete
get "signup", :to => "devise/registrations#new"
end
resources :users do
member do
get 'settings', to: 'users#edit'
end
end
My application_controller.rb
class ApplicationController < ActionController::Base
...
def after_sign_in_path_for(resource)
redirect_to user_path(:user_id=>current_user.id)
end
end
Shouldn't the resource :users block take care of creating a user show path? I do have a show method in my users_controller.rb. Please help, I've been trying to get this working for 2 days now.
My problem was that I was redirecting in the after_sign_in_path(resource) method instead of just returning the path:
def after_sign_in_path_for(resource)
return user_path(:user_id=>current_user.id)
end
is the correct way to do this.
I'm struggling with getting devise to redirect to a user's profile page after signin. My routes file looks like this:
get "profiles/index"
get "users/index"
get "users/show"
authenticated :user do
root :to => 'home#index'
end
root :to => "home#index"
devise_for :users
resources :users
scope ":username", :as => "user" do
match '/', :to => 'profiles#index'
end
I would like it to redirect to /myusername which the user's profile page. Thanks for your guys' help.
If you want to change the sign in redirect you can override the after_sign_in_path_for method by adding a new SessionsController as so:
class SessionsController < Devise::SessionsController
#after_sign_in_path_for is called by devise
def after_sign_in_path_for(user)
"/users/#{user.username}" #adjust the returned path as needed
end
end
As Ashikata mentioned you need to change the devise routing to the following if you're changing the session controller.
devise_for :users, :controllers => { :sessions => 'sessions' }
Alternatively, adding that modified after_sign_in_path_for method to your application controller should do the trick.
I'm working on a Rails-based API. I recently started attempting to version it. (I'm using the Versionist gem, in case it matters) One version ('v2') uses Devise and Omniauth to authenticate users through Facebook/Twitter.
I want all the routes associated with this version to have the appropriate version prefix (so users/:username/foo becomes v2/users/:username/foo, etc.), but I've already found out that putting devise_for inside the api_version block prevents the Devise helpers (current_user, user_signed_in?, etc.) from working, so it continues to live outside the block:
routes.rb:
devise_for :user, :path => '', :controllers => {:omniauth_callbacks => 'users/omniauth_callbacks'}, :skip => [:registrations, :confirmations, :sessions, :passwords]
api_version(:module => "V2", :path=>"v2") do
resources :authentications, :only => [:update, :destroy]
devise_scope :user do
post 'login' => 'sessions#create', :as => 'user_session'
get 'logout' => 'sessions#destroy'
post 'password' => 'devise/passwords#create'
put 'password' => 'devise/passwords#update'
end
end
Everything seemed great... except the Devise-generated omniauth routes:
rake routes output:
user_omniauth_authorize /auth/:provider(.:format)
user_omniauth_callback /auth/:action/callback(.:format)
Now, some google-fu revealed that there's a devise configuration setting for this, so I added the following to our devise initializer (config/initializers/devise.rb):
Devise.setup do |config|
config.omniauth_path_prefix = 'v2/auth'
end
Now, rake routes produces paths that look sensible:
user_omniauth_authorize /v2/auth/:provider(.:format) v2/users/omniauth_callbacks#passthru {:provider=>/(?!)/}
user_omniauth_callback /v2/auth/:action/callback(.:format) v2/users/omniauth_callbacks#(?-mix:(?!))
However, when I attempt to access this route by calling api.localhost/v2/auth/facebook, I get a routing error:
ActionController::RoutingError (No route matches [GET] "/v2/auth/facebook")
Any idea what's going on here?
You are missing the provider name in the routes so they don't match the facebook part in /v2/auth/facebook. The correct route destination should look something like v2/users/omniauth_callbacks#(?-mix:facebook).
Have you specified the provider in the user model?
devise_for ..., :omniauthable, :omniauth_providers => [:facebook]
For the record, I'm using Rails 3.2 and Devise 3.0 and the altered route seems to work (I haven't gone further yet to see if something else will break).
I would like my users to be redirected to the home page if they visit "/users/sign_in" after they have already signed in. How could I do that?
In your controller action for the sign in page (registrations probably if you are using devise). You will have to override the controller if you haven't already.
def new
if current_user
redirect_to home_page_url
else
#current logic for sign in method (super) if you currently don't have it implemented
end
end
I also discovered a way of doing this from the router.rb file; that is much much easier than doing it from the router, which would require me to override the devise controllers.
authenticated :admin do
root :to => 'admin/dashboard#show'
end
authenticated do
root :to => 'dashboard#show'
end
root :to => 'landing#show'
http://rubydoc.info/github/plataformatec/devise/master/ActionDispatch/Routing/Mapper:authenticated
Add the following to your routes.rb:
match "user_root", :to => "site#show" # where SiteController#show is your home page