Is there a simple way to have persistent form data in SInatra? Or does it require I write form variables to a file and read them manually? - ruby

I have a form in Sinatra with 4 text fields. When the page is closed and then reopened I would like to fill the text fields with the values that were last submitted.
I am doing this currently by writing each variable to a file in the same folder, and then reading them back when the program starts. I would like to know if there is an easier way to do this.
Is there an already implemented system in Ruby/Sinatra that allows me to write form data to a file and then read it back somehow?

The best way to handle such situations in sinatra is to use sessions instead of having to write it to a file and retrieve it.
Enable sessions in your configure block.
configure do
enable :sessions
set :session_secret, "secret"
end
in your before block
before do
session[:user_input] ||= []
end
Then pass the user input values in the sessions object. From there it can be retrieved as long as the user sessions is active.

Related

Using laravels {{old}} on dynamically created inputs

I have a form which allows a user to create an unlimited number of fields. If this forms fails validation I want the user to return to this page with the form populated with their previous input values - i.e. I want these fields to persist.
With a normal form I could do this with {{ old 'title' }}, however, these additional fields are being generated through JavaScript and so I cannot add this PHP snippet. What is the best way for me to retrieve these previous input values?
3 ways to do this, cache, sessions and cookies.
cache and sessions are server side which is much better for security, however it will take extra time and effort for setting up, but if the data is not sensible and can be passed within cookies, better to the cookies.
The best thing about cookies for your current situation is: you can set it up directly from your front end JS code.

Avoid multiple logins with the same username and password

In my application I have a login page and I need to prevent multiple logins from the same user (same username and password). I have used different methods like having a boolean value and updating it from true to false. But it has the drawback that whenever a user closes her browser (without logging of) the flag is not updated.
Are there any ways to achieve that by using session_id or something along those lines?
I will use Devise and enable trackable which will save last_sign_in_at, last_sign_in_ip, current_sign_in_at, current_sign_in_ip into database. Then simply inherit Devise::SessionsController and override the action create to check if current IP is the same as last_sign_in_ip and last_sign_in_at is not before half an hour ago.

Storing multiple CAPTCHA solutions in a session

I'm implementing a 3D CAPTCHA for my website.
My original idea was to store the expected captcha solution in a session variable. After a user submits a form, I'd compare it with their response.
What happens if the user opens my website in multiple tabs though? For each tab a new CAPTCHA challenge is generated and the expected response variable in the session is overwritten.
Now consider the user submits a form in an "old" tab. Since the expected response variable in the session has been overwritten, they won't pass the test.
Should I worry about this? How would you deal with it?
That is the general approach for captchas and sometimes a reason why they do not validate.
This is a goood read http://www.sitepoint.com/captcha-inaccessible-to-everyone/ why not to use captcha
You could however add them in an array instead and see if the answer exists in array.
You are not stating which language you are using otherwise i could provide some code.

Getting unique session ID in Sinatra

I have a simple web app built using Sinatra, with sessions enabled.
If I am understanding correctly, the session data is stored in an encoded cookie. As the session data changes, the value of the cookie will change also.
I need a unique session identifier that remains constant through the entire session. Is there such an identifier. Or must I create my own unique value and store it in the session myself?
Thanks!
EDIT: In a comment below I thought of a useful comparison. If I had a Java servlet, I would use the JSESSIONID as a unique identifier. I need a Sinatra equivalent to the JSESSIONID.
Because this is one of the first Google results for the subject and it contains no actual examples, here is a simple way to create your own SESSION_ID. We're relying on probability and cryptographically secure randomness to keep our IDs unique.
This is the only thing I put in my cookies. I keep all the other data on the back end to prevent anyone from tampering with it.
require 'sinatra'
require 'securerandom'
# The configuration here is just an example. Use your own secret, etc.
use Rack::Session::Cookie, :key => 'SESSION_ID',
:expire_after => 60*60*24, # == one day
:secret => 'This one time, at band camp...'
before do # Before every request, make sure they get assigned an ID.
session[:id] ||= SecureRandom.uuid
end
get '/' do # Show off your new ID.
"Your ID is #{session[:id]}"
end
In a sinatra app if you print out session.keys, you'll see there is a "session_id" that contains the unique id for the current session. You can access this 64 byte string as session["session_id"].
As the session data changes, the value of the cookie will change also.
This is true only if you're using cookies to store your session data, which is the default session storage used by sinatra. More details at http://rubydoc.info/github/rack/rack/master/Rack/Session.
I need a unique session identifier that remains constant through the entire session. Is there such an identifier. Or must I create my own unique value and store it in the session myself?
You can access sinatra session id using the id instance method on the session instance of Rack::Session::Abstract::SessionHash. More details at http://rubydoc.info/github/rack/rack/master/Rack/Session/Abstract/SessionHash#id-instance_method.
Example:
require 'sinatra'
configure do
enable :sessions
end
get '/' do
session.id
end
From what I can tell JSESSIONID is used to pass the session around in a query string, and Sinatra doesn't have something like that, at least not easily accessible. Sinatra uses Rack for session management, and by default uses a cookie to store all session data. There are other session options in Rack, like memcached, where a unique session id is stored in a cookie, but even there Rack abstracts that away so you don't ever need to see the session id (though it is still accessible, see the documentation).
If you want to go that route then look into messing with the Rack middleware in Sinatra, but if all you need is a unique id, then it would probably be easier to generate one yourself and store it in the session.

How do I pass data using sessions in Ruby CGI?

I am working on a guess-a-number game with Ruby that will be online. I know I need to pass the SESSION somehow to keep the number that they are guessing, but I have tried a ton of methods with no luck. My code is here.
Any thoughts on what I can do get this code working? I have declared each of my sections.
A session is, usually, a combination of a cookie (session cookie), or some session id tacked onto the url, which has some unique identification of the current "session" and a way to save the data on the server and retrieve it when given the id from the cookie.
So I would set a cookie based on for example ip + Time.now.to_i and then save that ID and the values I want set into a database or a text file on the hard drive. Note that there is probably a lot better ways to create a unique ID but aim for the simple stuff first. :)
I also recommend that you look into CGI::Session which you require with require 'cgi/session'.

Resources