Retrieve session with session_id in Ruby On Rails? - ruby-on-rails

I want to access the session of a user from a different domain than the one that I initiated the session. Can I use session.session_id of the user and then retrieve the session hash of that user ?
Thank you

If it's on a different domain (i.e., not a subdomain), there's no way to get the session info (cause it's stored in a cookie)—you'll need something else (see this question). If it's a subdomain, I think there's a neat way to do it automatically by setting the cookie's domain (look in environment.rb's config.action_controller.session, try setting :session_domain)

It looks like you could use something like:
CGI::Session::ActiveRecordStore::SqlBypass::find_by_session_id(session_id)
However, I'm not sure if that's a good idea or not -- and in this case it is only useful if you're using the ActiveRecordStore. Not sure what else is available on the other stores, but if you poke around under actionpack/lib/action_controller/session/* you'll probably get a more definitive answer.

Related

Session exists even after destroying

I have a session variable with name session[:computerid] and while login it's set to "comp--001". While sign out i am deleting session like as follows
session.delete(:computerid)
But after doing that also if i debug session[:computerid] it's showing value "comp--001".
My session_store.rb file has the following code:
Rails.application.config.session_store :cookie_store, key: '_sample_app_session', :domain=>:all
Could you suggest me a solution to solve this?
Could you try setting it to nil? Like:
session[:computerid] = nil
This is the most common pattern in rails.
Hope it helps!
Good luck!
Ruby on Rails doesn't know what you want to keep or not when a user signs-out.
Say for example you have a session[:language] that is useful for every user, even anonymous ones. You wouldn't want to erase it to display the default language after the user has gone through the trouble of selecting one in particular.
So, delete the session objects you need to, like session[:user]=nil and keep the rest. If you have a lot of them to delete, make yourself a logout helper.
If you know you can swipe the whole session, use the reset_session

"Restful" resources in rails: session[:user_id] = user.id syntax when session is a resource but not a model

Working through authentication in RailsCasts, there was one where I didn't understand something completely fundamental and important (it's pro, sorry - you need to be subscribed to access it).
He creates a user model with an email and encrypted password (has_secure_password).
Then he makes a new controller called Sessions, and declares it as a resource in the config. i.e.
resources :sessions
Then, inside the sessions controller, he defines the create method like this:
user = find user and authenticate
if user
session[:user_id] = user.id
else ...
But sessions as a model doesn't exist. For instance, if I open up my console and write
sessions[:user_id] = "hello"
it throws. Does anyone have an explanation or a link to this very basic concept that I'm missing?
Thanks!
Edit: Thanks Sanfor. Typo fixed, also for markup plus most importantly an answer!
I suppose you have copied the session as sessions in your question, is that correct? The screen cast is revised, so you'd need to be subscribed what I'm not nowadays so can't confirm it more than what comments say.
Now to the actual answer, the session is Rails internal reference to the actual session on hand as described here and for that reason you can't see the model for it created.
Simplistic explanation:
session is just a hash and stored as a cookie. (Unless you specifically instructed Rails to store it in the database). Models are typically ActiveRecord based and have some behavior.
You can add to it by simply
session[:some_thing] = "Info for session"
session[:store_this_too] = "Some other info to track for this session"
The session hash is created by the controller-related class/modules and rails console doesn't load them. Therefore, it is not available in the console.
Here's a pretty old Railscasts which explains a bit more. And this which takes the model-based approach. Bear in mind they are from the old days.

Steps to create my own authentication system, need some guidance

I want to learn how to create my own authentication system, please provide some guidance if am doing this wrong.
I will create a Module in my /lib folder /lib/auth.rb
I will require this module in my ApplicationController.
when a user enters their email + password, I will call a method that will do a lookup in the user's table for a user with the same email, I will then compare the passwords. (i'll add encryption with salt later).
If the user entered the correct credentials, I will create a row in the Sessions table, and then write the session GUID to a cookie.
Now whenever I need to check if the user is logged in, or I need the user object, I will check if the cookie exists, if it does, I will lookup the session table for a row with the same guid, if it exists, I will return the session row and then load the User object.
I realize there are many suggestions one can give, but in a nutshell does this sound like a workable solution?
Now to make this usable, I will have to make some helper methods in my ApplicationController right?
How will I access the current_user from within my views?
P.S I know of other authentication systems, I just want to learn how to create my own.
The basic logic you're following is correct. Of course you can always expand on this with features that you need. For instance, you'll need helper methods for things like "logged_in?" and "current_user". Also, you might want to add session expiry, or session retention as a "remember me" feature.
Go for it, you won't learn authentication systems better than building your own then figuring what's wrong with it.
You should really check out the authlogic gem on github.
http://github.com/binarylogic/authlogic
It also has great instructions on how to set up your users.
After Faisal said what I would say, I only give you answer to the last part of your question:
"How will I access the current_user from within my views?"
try something like this:
class User < ...
def self.current=(u)
#current = u
end
def self.current
#current
end
end
In your views (or any part of your code) you can call User.current. Your controller has to assign a validated user to User.current. Your filters can react to "if User.current.nil?" and so on.
If you want to be thread safe, you may use a thread variable instead of #current:
Thread.current[:current_user] = u

Ruby on Rails: how can I store additional data in the session for authlogic

I'm using Authlogic to authenticate users.
I understand how to create and use sessions, but want to store an additional id variable in the current_user session created by authlogic.
Can I just do something like this:
session[:authlogic_sess_name] = #extra_id.id
However, I'm not sure what the authlogic session is named though or how to access it.
Thanks!
Why would you not just store the value in the session?
session[:extra] = #extra_id.id
The Authlogic current_user is simply a value in the current session, managed by the Rails stack itself.
I agree with Toby, if you don't need this additional attribute to be on AuthLogic's UserSession object, then it may be simpler to store the value in the session hash itself.
But in my specific case, and perhaps in yours too, I have information that I want on the UserSession record specifically rather than the session hash, because I want to access it in a callback in the UserSession model, where "session" is unavailable.
Here is an older blog post describing how to store an additional attribute on UserSession:
http://railsblog.kieser.net/2010/03/authlogic-custom-logins-and-persisting.html
EDIT: I didn't have much luck with this approach myself. To do the things that required information from the session hash, I put that logic in the controller instead of the model.
AuthLogic actually has certain callbacks that execute controller methods. For instance, AuthLogic will call last_request_update_allowed? if your controller responds to that, right before setting last_request_at.

Rails saving IP address with every create/update request

I'd like to do the following:
define a before_filter in application.rb that extracts the user's IP address and stores it anywhere, preferably in the session.
define two before filters in all my models as before_create and before_update that add the current user's IP to the object to be stored.
Problem: I cannot access session[] neither env[] in a model. Can anyone help with a standard solution that I don't know yet?
Regards
Jason
Try this. In your user model add a class attribute accessor
cattr_accessor :current_ip
In your application controller add:
before_filter :set_current_ip
protected
def set_current_ip
User.current_ip = request.env['REMOTE_ADDR']
end
Then in your model you should be able to just call User.current_ip
We do something similar to get the current_user object passed through.
You're having trouble doing what you want because Rails is designed not to allow you to have access to session information in your models. It's the classic separation of concerns with MVC. Models are meant to work independently of your other layers, and you'll be thankful they do when you start doing things with Rake or other system tasks where you won't have a session.
The
cattr_accessor :current_ip
is a horrible approach. It's a hack and it should be apparent why. Yes, it may work, but it's the wrong approach to this problem.
Since you're tracking "who" did "what" by their IP, the logical place for this to happen is in the controller layer. There are several approaches you can take, including using CacheSweepers as auditors, as outlined in the Rails Recipes book. CacheSweepers can observe models but also have access to all controller information. Using the ditry attributes in a rails model, you can see exactly what changed.
#user = User.find_by_login "bphogan"
#user.login = "Brian"
#user.save
#user.changed
=> ["login"]
#user.changes
=> {"login"=>["bphogan", "brian"]}
#user.login_was
=> "bphogan"
Combine this with the session info you have and you have a pretty awesome auditor.
Does that help?
If you want to save the IP in the session, you can create a before filter in the applicationController. Like this, for each action, the filter is called and the ip is stored.
authlogic is a plugin to manage users login/sessions etc, it has a built in option to track the users IP
What you really need is a versioning plugin - I suggest having a look at one of the fine solutions at http://ruby-toolbox.com/categories/activerecord_versioning.html
Edit: archived version of that link (was 404 since sometime in 2012): https://web.archive.org/web/20111004161536/http://ruby-toolbox.com:80/categories/activerecord_versioning.html

Resources