Do we need to delete session variables after user logout? - ruby-on-rails

In Ruby on Rails :
suppose I am having session[:my_var] = 'my_val'
So here my question is :
Do we need to set session[:my_var]=nil before user's sign-out?
or it will auto release the memory it has.

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 like #adcosta said.

If you want to clean your app session use reset_session.
If you only want to clean a var do session[:my_var]=nil
See Sessions in rails

If you have set up your authentication code properly, that should handle the release from memory. Here is how I did it in one of my apps:
#sessions_controller
def destroy
reset_session
redirect_to login_path, notice: 'Logged out'
end

Related

In rails 4.2, how to display a form for preview but ensure it cannot be submitted

I'd like to have a a form view that can, depending on circumstances, have submit functionality disabled in a bullet-proof way so that even a clever user could not edit the HTML source (via a browser extension) to re-add the submit button.
It seems one way to do that might be to somehow inject an invalid authenticity token that replaces the (valid) rails-generated one, so that even if a user somehow re-adds the submit button (by editing the HTML via a browser extension) it would still be an invalid submission.
My thought is to have some logic in the view:
- if #form_disabled # set by controller
- somehow_invalidate_the_authenticity_token?
How might one 'break' Rails form submission?
The purpose of doing this, instead of rendering the preview in a :show action, is to have the exact same view displaying both the live-form and the dead-form.
If I were you, I would use pundit.
It's pretty simple, and has few lines of code if you need to know how it works.
I'd start to write the code here, but I realize that the example at the readme fit your needs.
At the application controller add this
At the folder app/policies put the class PostPolicy, of course, you must replace "Post" with the name of your controller in singular (even if you have not a model with that name). The update? (and create?) actions should return true/false to indicate if user is allowed or not.
A few lines down on the readme, you will find the PostsController#update action, which call to authorize with the record before the update. I think you want do the same with create (then you need a create? method at the policy class).
Pundit needs current_user controller method, if you don't have it. Just follow the user customization instructions.
Of course, new and edit actions don't call authorize because they are allowed to everybody. Only the POST & the PUT/PATCH actions are forbidden.
Yes, it's more than a surgery of one line of code. But it's simple and the right way of give access to users.
After reading my other answer, I start thinking that you can do the same that Pundit does at the controller:
def update
if <unauthorized user>
flash[:alert] = "You are not authorized to perform this action."
redirect_to(request.referrer || root_path)
else
# all the update stuff
# ...
end
end

How can I lock the login system in rails?

I want to prevent all user except me to login to system in a period of time. How can I do that?
Like I login as hello.world#email.com and I have function to import data from big CSV file (about 20k record), so I want to prevent other user except hello.world#email.com to login while the data is importing.
I try to use:
Set flag on all user as locked: This one is not good when the system grows and has a ton of users
Add a class variable to ApplicationController like ##system_lock_only_for and keep hello.world#email.com inside and have a before_filter like
if ##system_lock_only_for && ##system_lock_only_for != current_user.email
redirect_to somewhere_path
end
But I'm not sure it is the best way.
How could I better solve this problem?
PS. I'm using Devise with Rails 3.2
If you don't want users to access it then you could just shut off the web server and do your import from the command line.
Alternatively you could set a global variable that you check on each request and spot out a maintainence page
Try this:
We may use session for Authentication.
Refer this link:
https://github.com/binarylogic/authlogic/blob/master/lib/authlogic/session/magic_columns.rb#L65
def last_request_update_allowed?
action_name != "check_session_timed_out"
end
use redirect_to somewhere_path when session is expired. That's it.

How to store where a new user was referred? Using Rails + Devise

I have a rails app that uses devise. I'm curious to know, is it possible in the User table to somehow track where a new user came from, the HTTP referrer?
I'd like to know which came from Facebook, Twitter, LinkedIn, Google+ in order to track a viral loop.
Any ideas? Seen anyone do this? Possible? Where should this live in the rails app? Still very new. Thanks
It could be done like this. May require some tweaking and fixing but You'll get an idea
Make before filter for Application controller, you will call it for any action
def landing_filter
if from_other_site(request.referrer) and !session[:referer].blank?
session[:referer] = request.referrer #you don't want to delete first entrance
end
end
from_other_site should be the method which will check domain name in referrer url, if it match your then return false, otherwise true
in devise/registration/new.erb.html view add in form hidden field
<%= f.hidden_field :referrer, session[:referrer] %>
and don't forget to add migration with new database field for user
Save referer somewhere and after creating a user copy information to user table. Using session to save referer works but permanent cookies are better. Cookies can persist the information even when user closes browser and comes again in the next day.
# so basically in ApplicationContreller using before_filter
def referer_before_filter
if cookies[:referer].blank?
cookies.permanent[:referer] = request.env["HTTP_REFERER"] || 'none'
end
end
# and in signup action somewhere else saving that information
#user.referer = cookies[:referer] # or maybe to some other table
Instead of modifying every action you can also use rails sweepers/observers to handle automatic saving every time an object is created.
A good gem to automatically save referer and other needed information is
https://github.com/holli/referer_tracking . You can choose do you want to save information manually or use sweepers to do saving automatically.

Rails3 / Sessions / Active_Record_Store / Signout --> How to delete the cookie and the record in the Sessions table?

Using active_record_store to store information relating to my users' sessions, and having a great time with how easy it is, but also finding that it is so easy that I am not taking the time to understand it.
I recently found that when users sign out of my site, nothing in the Sessions table is deleted, and so I have very quickly amassed a rather large Sessions table.
What I'd like to do is: Delete the record in the Sessions table when the user signs out AND delete the cookie on the user's computer. What do I have to add to my signout routine to accomplish this?
As of now, all that I'm doing is wiping the user id from the session data, which is clearly not sufficient. I thought I could just delete the record from Sessions by calling the destroy() method on the ActiveRecord object, but, I don't have the session ID. (Maybe I just don't know how to get it?)
I'm a freshman of rails,but i suggest you try this :
rake db:sessions:clear
Only because this is the top answer on google when searching for "rails active_record_store clear table", here is the answer on how to clear the sessions-table: https://stackoverflow.com/a/10088725/1474934
session[:user_id] = nil
session[:username]= nil
flash[:notice]= "You have been Logged out"
redirect_to(:action => "login")

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

Resources