Session data not being saved in Sinatra simple authentication - ruby

I created a simple authentication for Sinatra, however the session object seems to be cleaning up ALL custom keys. For example, when user logs in:
session[:user_id] = current_user.id
This is effectively stored in the session object for the current request. When a new request occurs the session[:user_id] is not there anymore. Session is active, cookies are enabled. I tried everything I can't figure out what it wrong (here is the all the relevant code: https://gist.github.com/ksiomelo/7656296).
application:
use Rack::Session::Cookie , :secret => "82e042cd6fde2bf1764f777236db799e"
enable :sessions # for flash messages
helpers:
def require_auth
unless session[:user_id]
flash[:error] = "You need to be logged in."
redirect to("/login")
end
end
def current_user
#current_user ||= User.find_by_id(session[:user_id]) if session[:user_id]
end
signin:
authorized_user = User.authenticate(params[:email],params[:password])
if authorized_user
# update session / redirect
session[:user_id] = authorized_user.mongo_id.to_s
session.options[:expire_after] = 2592000 unless params[:remember].nil? # 30 days
# redirect to the wizard
flash[:info] = "Welcome back #{authorized_user.first_name}"
redirect to("/home")

You should likely try to set a provider for session handling, e. g.:
use Rack::Session::Pool, :expire_after => 2592000
Glad to help.

Related

sessions arent working on sinatra

So i've been using sinatra and well no matter what i try i cannot seem to get sessions to work as intended.
Im enabling session/cookies with the following:
use Rack::Session::Cookie, :key => 'localhost_tester',
:path => '/',
:expire_after => 14400, # In seconds
:secret => 'secret_stuff'
And im trying to create a login page, the post data seems to be getting sent but no session is being created. This is what im using:
get '/account-login' do
#title = 'Adnetwork'
erb :accounts
end
post '/account-login' do
email = params[:email]
password = params[:password]
user = User.new()
if user.login(email, password)
#session isnt being made...
session['email'] = email
#redirect once session is complete
redirect to'/dashboard'
else
erb :accounts
end
end
The session wont actually be called "email" thats just an example i was using while testing. But it never actually creates the session. I have cookie editor plugin on chrome to see whats happening and the only thing thats being created is a session called "localhost" tester.
Am i being an idiot and doing it all wrong or is it something else that im missing?

session[:id] variable not being picked up within another route from sinatra

I am following this tutorial here on setting up a user login https://learn.co/lessons/sinatra-user-auth
It says that in order to save a session[:id] in my route I would do something like this:
post '/login' do
#user = User.get_id(params['email'],params['password'])
session[:id] = #user # equals a numeric value of the matching user
redirect '/home'
end
however, when i get to my /home route I am no longer able to access the session[:id] that was set in my /login route, it returns nil
# this doesnt return the session id
# consequently I cant lookup my user records
get '/home' do
#user = User.object(session[:id]) # looks up user object with numeric value
erb :home
end
I have tried enabling sessions in my config controller, that didnt work either
module Controllers
class ApplicationController < Sinatra::Base
# . . . .
configure :production, :development do
enable :sessions, :logging
end
end
end
how do I make my app persist the session[:id] between routes?
Have you tried enable :sessions after you require your sinatra gem in your sinatra app? Not in your controller

Devise not storing sessions and losing credentials after redirect

It is a VERY strange bug and I am leading with it for 24 hours. It was working well and suddenly it started to fail.
The problem:
When I want to login with Facebook, the app redirec to Facebook permissions request, go back, save the update in the account model (access_token, and updated_at), but I am redirected to the home without permissions to access to signed_in sections.
My stack is:
Rails4, Devise 3.0.0.rc, Omniauth, Omniauth-facebook 1.4.0.
The app only accept login with Facebook.
Take a look:
Omniauth controller: account_signed_in? = true
class Accounts::OmniauthCallbacksController < Devise::OmniauthCallbacksController
def facebook
# You need to implement the method below in your model (e.g. app/models/user.rb)
#account = Account.find_for_facebook_oauth(request.env["omniauth.auth"], current_account)
if #account.persisted?
sign_in_and_redirect #account, :event => :authentication #this will throw if #user is not activated
puts account_signed_in? # <-- true
set_flash_message(:notice, :success, :kind => "Facebook") if is_navigational_format?
else
session["devise.facebook_data"] = request.env["omniauth.auth"]
redirect_to new_account_registration_url
end
end
ApplicationController: account_signed_in? = true
class ApplicationController < ActionController::Base
# Prevent CSRF attacks by raising an exception.
# For APIs, you may want to use :null_session instead.
protect_from_forgery with: :exception
private
def stored_location_for(resource_or_scope)
nil
end
def after_sign_in_path_for(resource_or_scope)
puts account_signed_in? # <-- true
current_account.pages.empty? ? new_page_path : pages_path
end
StaticController (home) account_signed_in? = false
class StaticController < ApplicationController
def home
puts account_signed_in? # <- false
render layout: 'home'
end
I don't know if can there be something that disturb the normal flow of sessions between Devise and Rails.
Found that!
The sessions weren't saved because of the domain parameter in session_store.rb:
BrainedPage::Application.config.session_store :cookie_store,
key: '_my_session', :domain => Rails.configuration.domain
Seems I had changed the domain configuration in development environment (added port, because I was using this var for other propose too), and I didn't realize the impact it could make.

How do I do a really simple Sinatra LDAP authentication?

I looked at the Sinatra docs and they only seem to reference HTTP authentication. I'm looking for a really simple way to control access to routes based on a user being authorised/authenticated via an LDAP server.
I've already built a class that does the LDAP bit and returns an LDAP object if the user has successfully authenticated and nil if they haven't:
>>DirectoryUser.authenticate('user', 'password')
#<DirectoryUser:0x007ffb589a2328>
I can use this to determine if they've successfully authenticated or not.
As a next step I want to splice this into a simple Sinatra app that provides a form to collect the LDAP user and password:
require 'directoryUser'
require 'sinatra'
enable :sessions
get '/form' do
username = params[:username]
password = params[:password]
haml :form
end
Then I want to only allow routes if the 'DirectoryUser' object exists:
get '/protected' do # Only if DirectoryUser object exists
"This route is protected"
end
get '/unprotected' do
"This route is unprotected"
end
I've spent hours trying to find an answer to this but so far and can't seem to find anything that works for me.
I'd probably go with something like this:
require 'directoryUser'
require 'sinatra'
enable :sessions
helpers do
def authorize!
redirect(to('/login')) unless session[:user_id]
end
end
get '/login' do
haml :login # with the login form
end
post '/login' do
user = DirectoryUser.authenticate(params[:username], params[:password])
if user
session[:user_id] = user.id
# Or: session[:logged_in] = true, depending on your needs.
redirect to('/protected')
else
redirect to('/login')
end
end
get '/protected' do
authorize!
'This route is protected'
end
get '/unprotected' do
'This route is unprotected'
end

Session values aren't kept

I'm using a JRuby(latest, 1.7 RC2)/Sinatra mix on the Trinidad server, for background info.
get "/" do
#user = session[:user] || [3,2]
puts session[:user]
haml :home
end
get "/signed_in" do
"#{session[:loggedin]}"
end
post "/signup" do
user = User.create(:username => params[:username], :password => Digest::SHA1.hexdigest(params[:password]))
session[:user] = user
session[:loggedin] = true
puts session[:user]
end'
What I expect as output is (with comments):
# blank line
#<User:0x4049839a>
#<User:0x4049839a>
But what I really get is:
# blank line
#<User:0x4049839a>
# blank line
And after the post, /signed_in will still have no value to output, when it really should be true.
Why aren't these values being kept? No, I'm not using shotgun, I do have sessions enabled, and I do have a session secret set up.
You cannot keep DataMapper resources in session variables. Instead put the key to your user object in your session variable and use a before helper to set #user = User.first(session[:user]) and use the #user instance variable throughout your application
Also, you do not need the session[:loggedin] entry, just use #user.nil?

Resources