Sinatra Authentication with Warden
For those projects that not need a huge power behind them using Rails, is a wonderful idea use Sinatra because is light and cool.
I'm new, working with Rails / Ruby / Sinatra ( ~ 1 year ago ) and I don't really know if exists something that help me to start a new project with some stuffs or abilities included and not to start from scratch, anyways, I decide to create some repos to use as project start, I will explain you now what this contain and if you found it useful then feel free to use.
Warden Configuration Steps
I will assume that you already know how to install and use Sinatra and also have knowledge about Ruby.
Add Warden gem referente to your GemFile
gem "warden", "1.2.1"
Require warden in your app file
require "warden"
Warden uses Rack::Flash and Rack:Session we must to register
use Rack::Session::Cookie, secret: "IdoNotHaveAnySecret"
use Rack::Flash, accessorize: [:error, :success]
Add Warden Configuration in your app file
use Warden::Manager do |config|
# serialize user to session ->
config.serialize_into_session{|user| user.id}
# serialize user from session <-
config.serialize_from_session{|id| User.get(id) }
# configuring strategies
config.scope_defaults :default,
strategies: [:password],
action: 'auth/unauthenticated'
config.failure_app = self
end
Add Warden Strategies for :password
Warden::Strategies.add(:password) do
def flash
env['x-rack.flash']
end
# valid params for authentication
def valid?
params['user'] && params['user']['username'] && params['user']['password']
end
# authenticating user
def authenticate!
# find for user
user = User.first(username: params['user']['username'])
if user.nil?
fail!("Invalid username, doesn't exists!")
flash.error = ""
elsif user.authenticate(params['user']['password'])
flash.success = "Logged in"
success!(user)
else
fail!("There are errors, please try again")
end
end
end
Route Configuration Steps
Route configuration are the easy part but important.
Warden "must" routes
# when user reach a protected route watched by Warden calls
post '/auth/unauthenticated' do
session[:return_to] = env['warden.options'][:attempted_path]
puts env['warden.options'][:attempted_path]
flash[:error] = env['warden'].message || 'You must to login to continue'
redirect '/auth/login'
end
# to ensure user logout a session data removal
get '/auth/logout' do
env['warden'].raw_session.inspect
env['warden'].logout
flash[:success] = "Successfully logged out"
redirect '/'
end
Application routes
To protect a resource is only need to call the Warden method authenticate!
get '/protected' do
env['warden'].authenticate!
slim :protected
end
Now every time the user hit /protected route without authentication Warden will send him to the login form.
Startup Project
If you want all of these step preconfigured to use as a start point in your new project feel free to fork the repo and use it
This repo use all this components
- Sinatra Link for Repo
- Warden Link for Repo
- Thin Link for Repo
- Foundation 5 Link for Repo
- Slim Link for Repo
- Rack-Flash Link for Repo
- Sqlite3 Link for Repo
Any comments, suggestion or correction is welcome