I am trying to use session mechanism to store information of an user that is logged like this: session[:user_id]=#user_id , and that its ok.
But when a new user login in the app, the variable session[:user_id] is updated to the new user id, making the first one perform requests with an invalid id.
I used different browsers, private browsers, a browser in a Virtual Machine and another one in the host, and still got the problem.
I appreciate some suggestions. Is it normal the session being shared between multiple users? There is another way to store some specific data, and prevent the share between users? I thought that session was unique, why that variable is changing? The same happens for cookies variable.
EDIT:
application_controller
def sign_in
if(password != "" && #user_id!= "" && jenkinsip != "")
#client = JenkinsApi::Client.new(:server_url => jenkinsip, :username=> #user_id, :password=> password)
if(#client.get_jenkins_version != nil)
session[:user_id]=#user_id
end
end
end
in html
Every time session[:user_id]=#user_id is called, the session[:user_id] is being set to whatever the #user_id variable is set as.
Try using||= instead of =
set the session withsession[:user_id]||= #user_id to only set session[:user_id] to #user_id when session[:user_id] is undefined.
Follow the excellent answer of koxtra and
also have a look on devise gem for the user authentication.
Devise will do everything for you like users signin, signup, creating sessions and many more functions. You have to only install the Devise
in your rails application.
Related
I'm currently building an app wich is working with Devise. Some actions allows the users to invite other users by entering their emails. But sometimes the users are not registered yet.
To avoid a multiplication of tables and conditions (between registered and non-registered users), I chose to create empty User (with email, id, and registred(false) variables). This allows me to always use the same user for different invitations, even if the user is not yet registered.
The idea is that when the user registers, it automatically retrieves all the information previously recorded by other users (in this case invitations)
However, Devise email is defined by default as uniq (across method :validatable).
During registration, I need to set the following condition:
if email does not exist
New User
elsif email exist && not registred
Update User with this email
else
message:'email already token'
end
I tried several solutions like :
RegistrationsController#Create :
#previous_account = User.where(email: params[:user][:email]).first
if #previous_account == nil && #previous_account.registred != true
#user = User.new(params[:user])
else
# This update the user with his password and other informations, but keeping the same id (to keep all the previous invitations)
#previous_account.update(params[:user])
end
or
User Model :
before_create :verif_exist
def verif_exist
pre_user = User.where(email: self.email).first
if pre_user != nil && pre_user.registred != true
pre_user.update(encrypted_password: self.encrypted_password, registred: true)
else
self.save
end
end
I don't know how to solve this issue, if anyone has the same specificities in his app, I would love to see your solution.
So I have this app that I'm making where users have profiles after they signup and input their information.
At the moment I'm trying to add a feature that allows for new unregistered users to go to a profile to see what the app is like before they need to sign up (I'm planning on putting a "try it for free" button on the home_controller#index action. For authentication, I'm using the Devise gem.
Currently, I've watched the Railscast (393) on this, but I can't figure out (after several hours of trying) how to implement guest users and log them in using Devise.
I've also read about 4 different solutions on SO, and have decided to stick to this one (how to create a guest user in Rails 3 + Devise):
class ApplicationController < ActionController::Base
def current_user
super || guest_user
end
private
def guest_user
User.find(session[:guest_user_id].nil? ? session[:guest_user_id] = create_guest_user.id : session[:guest_user_id])
end
def create_guest_user
u = User.create(:name => "guest", :email => "guest_#{Time.now.to_i}#{rand(99)}#example.com")
u.save(:validate => false)
u
end
...
end
I have this in my application_controller.rb and don't understand how I would use these functions in the home_controller#index to create a guest user and log into the profile when the "Try it" button is clicked.
I've tried manually creating a user, saving it without authentication and then using Devise's sign_in method on link like so: Try it! and also tried
Try it!
I tried this, but the profile throws some validation messages saying I need to log in to view it. I've also tried removing before_filter authenticate! on the profiles_controller but I can't seem to get this to work at all.
Would anyone know how to create a user on the button click, and auto sign them into a guest profile? Thanks a lot for any help, I'm completely lost here.
I think you have a misunderstanding on what a guest user is. You say that you want guest users to auto sign in, and that is wrong. Guest users can't sign in, because... Well, because they are guests. You want to create them, but not sign them in.
This is why you want these helper methods in your ApplicationController, because when you try to get the current_user, if that doesn't exist (nil), you will have a fallback (that is why you use the || operator), that will assign a guest_user as a current_user.
So, forget about using sign_in links for guest users and you should be fine.
I am new to ruby. I want to know when/where the Current user set. I know cookie will be generated for each URL request. And where the session details are stored? And where the current user set(in which file). Any one please explain briefly.
Hope you have a users table in your Rails application, so devise will automatically load all columns of users table in current_user.
It all depends on how you implement it. If you're using a library like Devise it has its own implementation, but usually such things are stored in encrypted Rails session store and on every request 'session' controller verifies visitor's cookie and only after that current_user is set to the User object from the session.
i prefer it in applicaton_controller..so that i can check where user_signed_in on every request and check the session ..if it exits then its ok else redirect_to login page..
for example in application_controller.rb
before_filter :check_current_user
def check_current_user
if current_user
#check if current user exists in our session
session[:current_user_id] = User.find(session[:current_user_id]).id
else
#if not ,then create new and set it to the session and return the current_user as u
session[:current_user_id] = User.create(:username => "guest", :email => "guest_# {Time.now.to_i}#{rand(100)}#example.com")
u.save!(:validate => false)
session[:current_user_id] = u.id
u
end
end
the above code is not perfect though..but i just wanted to show how current_user can be implemented to check current_user on every request using session and sets it in the session if there is no current_user as guest...
Is there a way to limit the number of sessions in Ruby on Rails application (I'm using Authlogic for authentication)?
I would like to allow only 1 session per user account. When the same user is logging on another computer the previous session should be expired/invalidated.
I was thinking about storing the session data in database and then deleting it when a new session instance is created but probably there is an easier way? (configuration option)
I just ran into a possible solution, if you reset presistence token you can achieve the intended behaviour:
class UserSession < Authlogic::Session::Base
before_create :reset_persistence_token
def reset_persistence_token
record.reset_persistence_token
end
end
By doing this, old sessions for a user logging in are invalidated.
Earlier I implemented it as you mentioned: add a session_key field to the users table and make sure that the current session_id is stored for the user on login:
class UserSession < Authlogic::Session::Base
after_save :set_session_key
def set_session_key
record.session_key = controller.session.session_id
end
end
Then in the generic controller do something like this to kick out a user when someone else logged in with that same account:
before_filter :check_for_simultaneous_login
def check_for_simultaneous_login
# Prevent simultaneous logins
if #current_user && #current_user.session_key != session[:session_id]
flash[:notice] = t('simultaneous_logins_detected')
current_user_session.destroy
redirect_to login_url
end
end
i do exactly what your talking about, assign a session id to each uniq session, store that id in a cookie and the associated session data in a table. Works well. My aim wasnt to limit users to a single session, but rather keep the session variables server side to prevent user manipulation.
I have added auhlogic in my Rails app to authenticate users. I have also included the code from the Reset password tutorial . All of it works, the only issue I have is that once a user registers he gets automatically logged in.
Anyone worked with authlogic, what would be the best & fastest way to disable the autologin after the registration?
You can use #save_without_session_maintenance:
#user = User.new(params[:user])
#user.save_without_session_maintenance
If you will use this way:
After registration save succeeds,
session = UserSession.find
session.destroy if session
You probably can loss your Admin session, who perhaps adding the user.
So, the better way will be is just to add some options to your model user.rb:
acts_as_authentic do |c|
c.maintain_sessions = false
#for more options check the AuthLogic documentation
end
Now it should work.
After registration save succeeds,
session = UserSession.find
session.destroy if session