Redirect to page before login - ruby-on-rails

right now I have a problem with login. I want the user to go the previous page where he/she pressed the login-button. In my code right now I just have redirect_to back which just sends the user back one level but I want it to be two levels. How do I do that?
class SessionsController < ApplicationController
def new
end
def create
user = User.find_by(email: params[:session][:email].downcase)
if user && user.authenticate(params[:session][:password])
sign_in user
redirect_to back
else
flash.now[:error] = 'Invalid email/password combination'
render 'new'
end
end
def destroy
sign_out
redirect_to root_url
end
end
Thanks!

one of the solution maybe store the url inside the cookies, and redirect to that url after sign in
cookies[:return_to] = {
value: request.fullpath,
expires: 1.hour.from_now
}
redirect_to sign_in_path
after login, just call
path = cookies[:return_to]
cookies.delete(:return_to)
redirect_to path

The simplest solution is to probably follow the outline that the devise gem provides in their how-to. TL;DR - store the path in the session and use that as your redirect after sign in.

Related

Redirect logged in user using Omniauth in Rails

I've created a login controller so that people can log in using Facebook. When a user logs in he gets routed to frontpage/show and when they logout they get redirected to the root_url and it shows the login page.
The problem is that when a user logs in through Facebook, closes the site and then revisits the page he also gets directed to the root_url and not frontpage/show.
I've used Omniauth with Rails for this.
This is my session_controller.rb
class SessionsController < ApplicationController
def create
user = User.from_omniauth(env["omniauth.auth"])
session[:user_id] = user.id
redirect_to '/frontpage/show'
end
def destroy
session[:user_id] = nil
redirect_to root_url
end
end
and my frontpage_controller.rb
class FrontpageController < ApplicationController
def show
end
end
I've tried adding
def show
if authenticate_user?
redirect_to :controller=>'dashboard', :action => 'index'
else
redirect_to '/public/example_html_file.html'
end
end
To the frontpage_controller but it gives the error ndefined methodauthenticate_user` which makes sence. But I believe something like this is the answer.
Well, i'm assuming that you're using Devise. So, you have the method authenticate_user! and not authenticate_user?.
Now, to check if the user is logged, you can use the user_signed_in? instead of authenticate_user? and your code should works.
More information about those helper methods here https://github.com/plataformatec/devise#controller-filters-and-helpers

Rails: redirect to previous page after login doesn't work

I am trying to redirect to the page from where I clicked login, but after logining in it doesn't redierect to previous page but stays on login page (although the user is already logged in).
Here is my code:
session_helper.rb
module SessionsHelper
def sign_in(user)
remember_token = User.new_remember_token
cookies.permanent[:remember_token] = remember_token
user.update_attribute(:remember_token, User.encrypt(remember_token))
self.current_user = user
end
def redirect_back_or(default)
redirect_to(session[:return_to] || default)
session.delete(:return_to)
end
def store_location
session[:return_to] = request.fullpath
end
end
sessions_controller.rb
class SessionsController < ApplicationController
include SessionsHelper
def new
end
def create
user = User.find_by_username(params[:session][:username])
if user && user.authenticate(params[:session][:password])
cookies.permanent[:remember_token] = user.remember_token
#redirect_to root_url,:notice => "Logged in!"
redirect_back_or user
else
flash[:error] = 'Invalid email/password combination' # Not quite right!
render 'new'
end
end
def destroy
cookies.delete(:remember_token)
#session[:user_id] = nil
redirect_to root_url, :notice => "Logged out!"
end
end
I also tried to write in create function in sessions_controller.rb
redirect_to request.referer
but it doesn't work.
Am I missing something?
Thanks for your help!
The problem happens at store_location.
Though you havn't said in question, I guess you probably put this method in before_filter. So, no matter GET or POST or other request, the request hit this filter at first and store location.
Now, in this case, actually the user has two requests. One is to #new by GET, and the other is to #create by POST. In the later, his last request to #new was recorded as the going back location. So you'll see you always go back to #new :)
The solution is to filter the location to be stored.
def store_location
disable_pattern = /\A\/user*/
session[:return_to] = request.fullpath unless request.fullpath ~= disable_pattern
end
This pattern could solve current problem but not exclusive. In practice you may see even JS/JSON requests has been recorded, so you may need to add more restrictions according to the specific case. For example, only apply before_filter on #show or #index, use white list, etc.
I think request.referer may not have worked because of a typo in the method. It should be request.referrer.

cookie persistence with omniauth and linkedin gem

I'm running a rails application that lets users successfully authenticate with LinkedIn and import their LinkedIn profile data. The (big) problem I'm having is that the cookie data associated with one user that signs in first persists even after they sign out, and is pulled in for another separate user after they authenticate through LinkedIn. The first user's data overwrites the second user's data...big problem.
Help is very much appreciated!
Here is my sessions_controller:
class SessionsController < ApplicationController
def new
end
def create
if env['omniauth.auth']
user = User.from_omniauth(env['omniauth.auth'])
session[:user_id] = user.id
redirect_to auth_path
flash[:success] = 'Signed in with LinkedIn.'
else
user = User.find_by_email(params[:session][:email])
if user && user.authenticate(params[:session][:password])
sign_in user
redirect_back_or user
flash[:success] = 'Signed in the old-fashioned way.'
else
flash.now[:error] = 'Invalid email/password combination'
render 'new'
end
end
end
def destroy
cookies.delete(:remember_token)
session[:user_id] = nil
redirect_to root_path
end
end
I was having the exact same issue. Somewhere in your omniauth configurations there should be a path configuration for where the user is redirected to.
Before
https://api.linkedin.com/uas/oauth/authenticate
After - This fixed everything for me and made the controller action always require an authorization when executed so that new users on the same computer would not automatically use last user's LinkedIn cookie.
https://www.linkedin.com/uas/oauth/authorize

Ruby on rails redirect upon login

Im following the tutorial on http://ruby.railstutorial.org
I've manage to get the part when user will get prompted to login when accessing a restricted page then be redirected back to the restricted page after logging in.
However, after the login, I've logged out and logged in with another user, i will get redirected back to the page, and not the default main page for a fresh session.
My session Controller
class SessionsController < ApplicationController
def new
end
def create
user = User.find_by_email(params[:session][:email])
if user && user.authenticate(params[:session][:password])
sign_in user
redirect_back_or user
# Sign the user in and redirect to the user's show page.
else
# Create an error message and re-render the signin form.
flash.now[:error] = 'Invalid email/password combination'
render 'new'
end
end
....
end
My session helper
module SessionsHelper
....
def redirect_back_or(default)
redirect_to(session[:return_to] || default)
session.delete(:return_to)
end
def store_location
session[:return_to] = request.fullpath
end
end
Add session.delete(:return_to) to create method
def create
user = User.find_by_email(params[:session][:email])
if user && user.authenticate(params[:session][:password])
sign_in user
session.delete(:return_to)
redirect_back_or user
# Sign the user in and redirect to the user's show page.
else
# Create an error message and re-render the signin form.
flash.now[:error] = 'Invalid email/password combination'
render 'new'
end
end

Rails - Incorrect username/password notice appears on page when login link clicked

I'm having a problem with a notice appearing when it shouldn't. When I click a link in my app to login, it's flashing the 'Invalid username/password combination' notice, even though I haven't typed anything in. I understand why I'm getting the message - it's because when I click the link, I haven't typed in a matching username and password, so the error fires. But I'm not sure how to fix this. I want the error to appear when the user does type in the wrong combo, but not when the page first appears.
In the code, the 'user' refers to an admin, and the customer is a customer. I'm using the same login page for both types of people.
Also, what I'd really like is that when the user does type in the wrong combination, their email address will stay in the field so that they don't have to type it in again. How would I go about doing this?
Thanks!!
Here's the updated controller code:
class SessionsController < ApplicationController
skip_before_filter :authorize
def new
end
def create
user = User.find_by_email(params[:email])
customer = Customer.find_by_email(params[:email])
if user and user.authenticate(params[:password])
session[:user_id] = user.id
redirect_to admin_url
elsif customer and customer.authenticate(params[:password])
session[:customer_id] = customer.id
redirect_to customer_path(session[:customer_id])
else
render :new, notice: "Invalid email/password combination"
end
end
def destroy
session[:user_id] = nil
session[:customer_id] = nil
redirect_to store_url, notice: "Logged out"
end
end
Set the flash notice only when login parameters where sent with the request:
# ...
else
flash[:notice] = "Invalid username/password combination" if params[:email] || params[:password]
redirect_to login_url
end
I suggest you wrap everything in if params and rerender the view instead of redirecting to preserve the email.
if params
if user ...
...
elsif ...
...
else
render :new
Try replacing your last else statement with this:
else
if params[:email] || params[:password]
flash[:notice] = "Invalid username/password combination"
redirect_to login_url
end
end
That should do the trick. In regards to your question about the email address remaining in the field when the user enters an incorrect password, check this link: here
The general gist of the solution would be to use 'render' instead of 'redirect_to' in your code to reload the page.

Resources