Ruby on rails redirect upon login - ruby-on-rails

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

Related

Trying to define two different values for same variable in one method. rails

I am trying to define two different values to the one variable inside a sessions controller. I am getting "syntax error, unexpected keyword_elsif, expecting keyword_end" and "syntax error, unexpected end-of-input, expecting keyword_end". Obviously there is something wrong with elsif, or my grammar here. i am wondering what I am doing wrong or someone tell me a different way to do this.
def create
unless user = User.from_omniauth(env["omniauth.auth"])
user = User.find_by(email: params[:session][:email].downcase)
if user && user.authenticate(params[:session][:password])
log_in user
redirect_to user
# Log the user in and redirect to the user's show page.
else
# Create an error message.
flash.now[:danger] = 'Invalid email/password combination'
render 'new'
end
elsif
user = User.from_omniauth(env["omniauth.auth"])
log_in user
redirect_to user
end
end
Try this,the error occurred because you were using elsif with unless which is not correct, you can only use else with unless.
def create
user = User.from_omniauth(env["omniauth.auth"])
unless user.present?
user = User.find_by(email: params[:session][:email].downcase)
if user && user.authenticate(params[:session][:password])
log_in user
redirect_to user
# Log the user in and redirect to the user's show page.
else
# Create an error message.
flash.now[:danger] = 'Invalid email/password combination'
render 'new'
end
else
log_in user
redirect_to user
end
end
Hope that helps!

Redirect to page before login

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.

how to redirect to the previous page or action after successful login

i have my own authentication set up i.e not using a gem like devise or others and its working well.
i have a before filter method
def authenticate_user!
redirect_to login_url, alert: "Please Login" if current_user.nil?
end
that is placed above some controllers to allow a login first before they can continue.
what i intend doing is that i want after a successful login, i want the user to be redirected to the previouse action instead of the root_url
my session controller that controls the login is bellow
def create
user = User.find_by_email(params[:email])
if user && user.authenticate(params[:password])
if params[:remember_me]
cookies.permanent[:auth_token] = user.auth_token
else
cookies[:auth_token] = user.auth_token
end
redirect_to root_path
else
flash.now.alert = "Invalid email or password"
render "new"
end
end

RailsTutorial.org Chapter9 session.delete issues

I'm following the tutorial on http://ruby.railstutorial.org
Specifically, chapter 9 (9.2.3)
http://ruby.railstutorial.org/chapters/updating-showing-and-deleting-users#top
I've managed to get the part when a user will get prompted to login when accessing a restricted page then be redirected back to the restricted page after successfully logging in.
I'm trying to get it so that after one redirects to the protected page, the next login attempt will direct back to the main user profile page, however, session.delete(:return_to) doesn't appear to be working and the user is repeatedly directed back to the originally saved protected page. Here's my code:
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 sign_in(user)
cookies.permanent[:remember_token] = user.remember_token
self.current_user = user
end
def signed_in?
!current_user.nil?
end
def current_user=(user)
#current_user = user
end
def current_user
#current_user ||= User.find_by_remember_token(cookies[:remember_token])
end
def current_user?(user)
user == current_user
end
def sign_out
self.current_user = nil
cookies.delete(:remember_token)
end
def redirect_back_or(default)
redirect_to(session[:return_to] || default)
session.delete(:return_to)
end
def store_location
session[:return_to] = request.url
end
end
Any help you can give would be brilliant! It seems like session.delete() simply isn't working.
The following block solved it. Nothing else needs to change.
def signed_in_user
unless signed_in?
store_location
redirect_to signin_url, notice: "Please sign in." #unless signed_in?
end
end
When I did the tutorial, my code had the first lines of the SessionsController#create method as just:
user = User.find_by_email(params[:email])
if user && user.authenticate(params[:password])
But, I can see that the corresponding code in the book has changed to:
user = User.find_by_email(params[:session][:email].downcase)
if user && user.authenticate(params[:session][:password])
I attempted to use that new code in my sample_app, but most of my tests ended up failing. So, for you, I guess test adding the downcase method to your params[:session][:email] call first, and if that doesn't work, try substituting the lines out for the session-less code above and see if it works.
Update
After looking at your code, as far as I can tell, these are your problems:
You're calling session.delete(:return_to) in SessionsController#create for some reason. This line can be removed:
app/controllers/sessions_controller.rb
def create
user = User.find_by_email(params[:session][:email].downcase)
if user && user.authenticate(params[:session][:password])
# session.delete(:return_to)
sign_in user
# ...
#...
end
Both lines of code in your UsersController#signed_in_user method need to be put in the unless block, not just the call to redirect_to:
app/controllers/users_controller.rb
def signed_in_user
unless signed_in?
store_location
redirect_to signin_url, notice: "Please sign in." #unless signed_in?
end
end
If you make these changes and run your tests, you'll still have a Nokogiri::XML::XPath::SyntaxError: on your call to
spec/requests/authentication_pages_spec.rb
it { should have_exact_title('title', text: full_title('')) }`
but I'm assuming this is a custom matcher you're planning to work on. If not and it's a mistake, remove it and all your tests will pass.

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

Resources