Ive read plenty of questions asking this exact question, but havent gotten a great answer.
Right now a user goes to the site, and enters their email in. After they click submit I would like to clear their session/log them out so that they could enter in another email address, so it will save to the DB.
My hacky solution was to call the reset session in my user controller after a user was saved. This did not work.
I then proceeded to call the sign_out method provided via devise on user save, but that did not work.
Does anyone have any thoughts/solutions?
user_controller.rb
def create
#user = User.new(user_params)
#if #user.save
#reset_session
#sign_out :user
#flash: 'User was successfully created.'
#User.find(user_params).forget_me!
#else
#render action: 'new'
#end
end
I did this using the following code
reset_session
#current_user = nil
Related
I've followed the tutorial on the following article for how to deactivate users:
https://github.com/plataformatec/devise/wiki/How-to:-Soft-delete-a-user-when-user-deletes-account
My question is, how do I make it so that when a deactivated user signs in, it shows them a page that allows the to reactivate their account? IE: "users/reactivate" with a button to reactivate?
I know I have to rewrite the default Users sessions controller of course, but I'm not quite sure at what point or how active_for_authentication is called, and how I can overwrite the redirect.
When a user attempts to log in, the request is routed to the create method of your sessions_controller.rb, where a session for this user is created if credentials are valid. Within that method, you just need to check whether the deleted_atcolumn is populated, followed by some branching logic to either redirect to whatever landing page you have for valid logins or your reactivation page.
Your code would look something like the following sample, but again, you didn't provide implementation details, so it falls to you to adapt:
def create
user = User.find_by(email: params[:session][:email].downcase)
if user && user.authenticate(params[:session][:password])
unless user.deleted_at.nil?
my_user_login_method
redirect_to user # or redirect to a dashboard/landing page/whatever
else
render 'reactivate' # this would be a view for your reactivation page
end
else
flash.now[:danger] = 'Invalid email/password combination'
render 'new'
end
end
In my application I am trying to enforce that users be signed in to preform certain actions. And when they try to preform these actions when not signed, they are redirected to the 'Sign-In' page, and once they have signed in, they are redirected back to the page they were trying to access. I have all of this working properly with the below code.
Controllers Code
if !(signed_in?)
session[:return_to] = newcompany_path
redirect_to signin_path
flash[:notice] = "You must be signed in to add companies."
else
#company = Company.new
#primary_field = ##fields
end
...
redirect_path = session[:return_to]
if user && user.authenticate(params[:session][:password])
sign_in user
session[:return_to] = nil
if (redirect_path == nil)
redirect_to user
else
redirect_to redirect_path
end
else
The issue I am running into is, if the user clicks away from the sign-in page without actually signing in, the session[return_to] variable is not cleared properly, and if they then go back to sign in later, they are redirected to the wrong page.
So, how would I set it up so if the user clicks away from the sign-in page, the session[:redirect_to] variable is reset?
You could pass the return_to path in query string parameter rather than the session and submit it alongside the sign in form so that it only applies for that form, rather than subsequent requests.
When redirecting to the sign in form, it'd look like:
redirect_to signin_path(return_to: newcompany_path)
Then, in your sign in form, make sure to include a hidden field with the return_to value, like:
hidden_field_tag :return_to, params[:return_to]
Then in your controller action for signing in, you'll check params[:return_to] rather than session[:return_to] to get the path you want.
Is this what you're looking for?
redirect_to request.referrer
In my application I have a user confirmation process. When a user signs up four things happen:
An account_status_id is set to 1 (unconfirmed)
The user is signed in (now current_user exists)
A new_account_confirmation_token is generated
A confirmation email is sent to the new user with a link that includes the new_account_confirmation_token
I initially tried to handle the confirmation link with this method. It finds the user without issue and the code flows through the update_attributes! method, however it wasn't updating the account_status. From what I can tell it is due to the fact that the current_user object exists, therefore the user Im trying to update is already "in memory". Is that correct?
def new_account_confirmation
#title = "Account Confirmation"
logger.info("User is not logged in")
#user = User.find_by_new_account_confirmation_token(params[:confirm_id])
if #user
#user.update_attributes!(:account_status_id => 2)
else
redirect_to root_path
end
end
My work around is as follows. The code below works but I'd like to know why the code above doesn't work. Why won't it update the account_status?
def new_account_confirmation
#title = "Account Confirmation"
if current_user
logger.info("User is logged in")
current_user.update_attributes!(:account_status_id => 2)
else
logger.info("User is not logged in")
#user = User.find_by_new_account_confirmation_token(params[:confirm_id])
if #user
#user.update_attributes!(:account_status_id => 2)
else
redirect_to root_path
end
end
end
Even if your user is "in memory" as you say, that's no reason for it not to update. I believe your update IS happening but you're just not seeing it because current_user is not in sync with #user.
I don't know how you're verifying that #user is not being updated but if update_attributes! is not throwing an error then it's being saved.
I'm a beginner programmer and am working on an email confirmation. Once users have registered it sends them to a page to enter a confirmation code, which will be sent to the email they used. If submitted correctly it saves the User and logs them in.
I had looked into using Devise and maybe that's the way to go, but it seems I would spend as much time learning someone else's code when I could learn to do it myself. My repo is Here.
What I was thinking of coding (in my User controller) is shaping up like this...what do you think? Am I completely off and would be better figuring out Devise/Authlogic or am I on the right track? I'm using rails 3.1. Any help would be much appreciated. Thanks in advance.
def confirmation_code_to_register(string)
#confirmation_code = #random number
end
def create_start
#user = User.new(params[:user])
#send email with #confirmation_code via ActionMailer
redirect_to page_to_enter_confirmation_code
email_authenticate
end
def email_authenticate
if #confirmation code user enters == #confirmation_code
create_finish
else
#sorry, you entered the wrong confirmation code.
end
end
def create_finish
if #user.save
sign_in #user
flash[:success] = "Welcome to the Site"
redirect_to #user
else
#title = "Sign Up"
render 'new'
end
end
Consider using Sorcery instead of Devise. There is Railscast about it.
https://github.com/NoamB/sorcery
It more simpler to use, and I think it fulfill your authentication needs.
PD: Check the Edit I did to your post. Try to use that syntax when you post code (just indent the code, no html markup)
EDIT:
And that code should be in the User model, not the controller. Try to keep your controller small, very small. Put all the logic you can in the models.
I've implemented authlogic in a rails site, and I'm trying to get openid to work correctly. So far, you can login just fine as long as you have an existing account, but not so much if you don't. I'd like to be able to automagically create a new account if the identity_url is not already in the database.
The problem is that I also need to store some additional info. if the user is logging in for the first time with their openid, I'd like to ask them to fill in basic info (name, email), BEFORE the account is created.
I've played around with a few methods, but nothing seems to be working.
Thanks in advance for any input!
acts_as_authentic do |c|
c.openid_required_fields = [:email,"http://axschema.org/contact/email"]
end
Will allow you to require an email. I'm unsure of how to require other fields, but maybe check that axschema.org page. There is no need for the user to fill anything out other than their OpenID provider URL.
Combining login and registration could be done with something like this (untested create method from UserSessions controller, like from the authlogic tutorial stuff)
def create
if User.find_by_openid_provider(params[:user_session]).nil? # or something like that
#user = User.new(params[:user_session])
if #user.save
redirect_to whatever_path
else
# handle error
end
else
#user_session = UserSession.new(params[:user_session])
if #user_session.save
add_message 'Login successful!'
redirect_to whatever_path
else
render :action => :new
end
end
end
Maybe try putting the additional information into a temp table of some kind, and keep track of the session the user is in. Once they have authenticated, connect the previously entered information with the OpenID information to create the real user.