Which controller and action are being accessed with Rails, Devise, and Omniauth - ruby-on-rails

I'm using Devise and Omniauth in my Rails 4 application. In my view I have a button to "Login With Facebook" that directs the user to user_omniauth_authorize_path(:facebook). This works as expected and sends the user to /users/auth/facebook. Then, that URL appears to be correctly redirecting the user to the Facebook login page.
How can I determine which controller/action are being used for this redirect? I would like to set a return_url before redirecting to Facebook. I was able to do this in my regular Session and Registration controllers by subclassing the Devise version and adding my code, like this:
class Users::SessionsController < Devise::SessionsController
def new
return_url = params[:return_url]
store_location_for(:user, return_url) unless return_url.nil?
super
end
end
Then, I tell devise to use my new controllers:
devise_for :users, controllers: { sessions: 'users/sessions' }
I'm trying to accomplish the same sort of thing with the omniauth functionality? Is there some way to find out which controller is being accessed when the user visits /users/auth/facebook? If so, can I subclass it and add functionality in the same way I did above?
UPDATE
I found the controller/action by running 'rake routes'. Here's what it says:
user_omniauth_authorize GET|POST /users/auth/:provider(.:format) users/omniauth_callbacks#passthru {:provider=>/facebook/}
So I was able to find the passthru method that is being used, but that has left me even more confused. It's in Devise::OmniauthCallbacksController and says:
def passthru
render status: 404, text: "Not found. Authentication passthru."
end
I'm confused how this method is resulting in the user being redirected to Facebook.

It looks like you can pass parameters to the user_omniauth_authorize_path, and then retrieve them in the callback URL using request.env["omniauth.params"]. So, I changed my link to: user_omniauth_authorize_path(:facebook, { return_url: '/test_redirect_path' }
Then in my OmniauthCallbacksController I added:
store_location_for(:user, request.env["omniauth.params"]["return_url"])
before the call to sign_in_and_redirect #user.
This seems to have done the trick.

Related

Get target path before authentication

I'm using Devise for user authentication in a rails application, and so certain routes are wrapped in a authenticate tag to allow access only to users who are logged in.
authenticate :user do
post '/user/orders/new', to: 'user/orders#new', as: :new_user_order
end
For example, when a user tries to create a new order when they're not logged in, they're redirected to a sign in page.
What I want is for the user to be directed to the new order page after logging in.
Currently, we're using request.referrer which redirects the user back to the page they were on before trying to create a new order. I can't seem to figure out a way of getting the path they were targeting before being sent to sign in.
Anybody know how I could do this?
Thanks
You need to provide a before filter for user authentication in the controller and not mention it in routes . Just put the following code in the controller and it should redirect to sign-up if the user isn't logged in -
before_filter :authenticate_user
You need to override Devise's after_sign_in_path_for(resource_or_scope) method, you can do it in application controller
def after_sign_in_path_for(resource_or_scope)
# new_order_path
end
Hope that helped!
You can persist the last url - in session[:bookmark] and by doing something like this -
prepend_before_filter :set_bookmark
def set_bookmark
session[:bookmark] = request.url
end
And within SessionsController, you can use value of session[:bookmark] if it exists or after_sign_in_path_for

devise: adding notice after sign up (with confirmable)

I added :confirmable to my Rails app subsequently. The problem is that when I sign up after adding :confirmable I don't get a notice displayed after the sign up for with telling me what happened, for instance:
You will receive an email with instructions about how to confirm your account in a few minutes.
Why doesn't notice appear and how can I add that notice after adding :confirmable?
Thanks for help
Notice does not appear because the devise is redirecting to your root path which is probably protected by devise authentication. When you hit root_path, you get redirected back to sign_in page (because devise couldnt sign-in the user since it is not activated yet). You can verify that by looking on your development log after you enter user information and hit "sign-up" button - you will see in the log one request for registering a user, then a request navigating to your root url (whatever is in your routes.rb) and then redirect navigation to sign_in page because of authentication.
During redirect all flash messages are lost (since flash messages are only valid for next request only) and when you get redirected from root_path to sign_in page, you are making to requests. So you either need to use flash.keep on the first request before it gets redirected, or change the after_sign_up path so redirection does not happen. I recommend changing after_sign_up path since it's easier and looks as a right way to go about it.
To do that, you need to use your own controller for registrations and add after_sign_up_path method that returns url for redirect:
# app/controllers/registrations_controller.rb
class RegistrationsController < Devise::RegistrationsController
private
def after_inactive_sign_up_path_for(resource)
new_user_session_path
end
end
#config/routes.rb
devise_for :users, :controllers => { :registrations => "registrations" }
I also recommend reading similar question to yours: Rails 3 and Devise: Redirecting to page following signup (confirmable)

Devise: user has to login again each time he closes the browser

I'm using Devise and Omniauth for user authentication.
I want the users to stay signed in for 2 weeks after the authentication. However, whenever the user closes the browser window and reopen it, he gets the login screen again.
What is the correct configuration for the user to stay connected even after the browser was closed and re-opened?
Check out this page on Devise's wiki:
https://github.com/plataformatec/devise/wiki/Omniauthable,-sign-out-action-and-rememberable
Basically, Devise does not call rememberable by default when using omniauth. If you wish to do so, simple call remember_me(#user) on your omniauth callback and Devise will do the hardwork for you. It will also use all the configuration options set in your devise initializer.
You have to extend the devise SessionsController to add cookies on log in and log out, so the controller will look like this one:
class SessionsController < Devise::SessionsController
# POST /resource/sign_in
def create
cookies[:sign_in] = "Sign in info you want to store"
# add this for expiration { :expires => 2.weeks.from_now }
super
end
# GET /resource/sign_out
def destroy
cookies[:sign_out] = "Sign out info you want to store"
super
end
end
Then you would have to add the following to your routes.rb:
devise_for :users, :controllers => { :sessions => "sessions" }
You may also set the cookie expiration time for 2 weeks.

Ruby on Rails Devise, how to change signin path when authentication fails?

I have recently implemented Devise into my new app, in conjunction with Omniauth, however I am unsure how to change the default signin path in Devise so that when I call:
user_authenticated!
It will redirect to the authentication controller page.
Any ideas how to do this?
EDIT: To better explain my problem ->
What I want is when a user tries to access a page that requires you to be logged in and then gets sent to users/sign_in by the user_authenticated before filter, however I want them to be redirected to /auth via user_authenticated! not users/sign_in.
In your controller:
before_filter do
authenticate_user! rescue redirect_to auth_url
end
I don't think I really understood your problem, but to redirect to a particular page this should be the implementation
class ApplicationController < ActionController::Base
private
def after_sign_in_path_for(resource_or_scope)
root_path
end
end
if you want to have another url for the sign_in process, in your routes.rb
devise_scope :user do
get "sign_in", :to => "devise/sessions#new"
end
and everything else you need at
https://github.com/plataformatec/devise/wiki
hope it's useful

How to redirect a user after registration when using Devise?

I am using Rails 2.3 and Devise to handle user registration / authentication.
I need to redirect a user to an external 3rd party website immediately after a user signs up for an account. Been looking in the code & online but cannot see how to do this.
How can I alter the devise flow to redirect the user?
The answer listed as the "correct" answer specifically refers to after sign_in... If you want to do redirect a user after sign_up you need to override the following:
def after_sign_up_path_for(resource)
"http://www.google.com" # <- Path you want to redirect the user to after signup
end
Full details can be found on the wiki.
Add to your Application Controller
# Devise: Where to redirect users once they have logged in
def after_sign_up_path_for(resource)
"http://www.google.com" # <- Path you want to redirect the user to.
end
Here is the list of Devise helpers you can use http://rdoc.info/github/plataformatec/devise/master/Devise/Controllers/Helpers
I hope that helps =)
If you are using Devise's confirmations (meaning the user is not activated immediately after they sign up), you need to overwrite the after_inactive_sign_up_path_for method.
# controllers/registrations_controller.rb
class RegistrationsController < Devise::RegistrationsController
def after_inactive_sign_up_path_for(resource)
"http://somewhere.com"
end
end
Make sure to tell devise to use your RegistrationsController.
# config/routes.rb
devise_for :users, :controllers => {:registrations => 'registrations'}

Resources