Vai al contenuto
Home » Costruiamo un sistema di autenticazione con Sinatra e Warden – Parte 3

Costruiamo un sistema di autenticazione con Sinatra e Warden – Parte 3

Nella prima puntata di questa mini
serie

abbiamo visto tutta la business logic per autenticare i nostri utenti, censiti
su un LDAP. Nella seconda
puntata

abbiamo visto all’opera Warden ed abbiamo
constatato quanto sia semplice farne il setup di fatto realizzando un solido
sistema di autenticazione con veramente poche linee di codice.

Oggi ci concentriamo con le rotte, le viste e come bonus track scriviamo uno
script che faccia funzioni di console per il debug,
Sinatra non ha infatti un equivalente a rails
console
per intenderci.

Quattro rotte, quattro

Ci servono 4 endpoint per gestire l’autenticazione dei nostri utenti.

Atterraggio

La rotta più semplice gestisce l’atterraggio di utenti non autenticati al
sistema. Solitamente a questo link si viene gentilmente accompagnati quando
si tenta di accedere ad una risorsa protetta.

get '/' do
  redirect '/auth/login' unless authenticated?
end

Quello che andremo a fare è unicamente presentare la maschera di login.

get '/auth/login' do
  haml :login
end

Il nostro login.haml (che andremo a posizionare nella directory views/
sarà simile a questo.

.container
  %form.form-signin{:action => "/auth/login", :method => "post"}
    %span#reauth-email.reauth-email
    %input#inputEmail.form-control{:autofocus => "", :placeholder => "Domain user", :required => "", :type => "text", :name => "user[username]"}/
    %input#inputPassword.form-control{:placeholder => "Password", :required => "", :type => "password", :name=>"user[password]"}/

Scopriamo quindi la seconda rotta che dovremo implementare, quella che gestisce
il submit della form.

Biglietti prego

Nella rotta che gestisce la POST ad /auth/login dobbiamo chiamare warden
e chiedere di autenticare il nostro utente. Se ci
ricordiamo

quando abbiamo definito le nostre strategie di autenticazione, abbiamo
implementato un metodo authenticate! che invocava il metodo opportuno
della classe User per autenticare il nostro utente.

Ora è giunto il momento di connettere i punti, quindi in risposta a questa
POST, passeremo la palla a Warden.

post '/auth/login' do
  env['warden'].authenticate!
  flash[:success] = env['warden'].message

  if session[:return_to].nil?
    redirect '/'
  else
    redirect session[:return_to]
  end
end

Ricordate che di default, quando abbiamo configurato Warden abbiamo indicato
/auth/unauthenticated come action nel caso l’autenticazione non vada a
buon fine.

Si ritorni in fila

La nostra terza rotta sarà quindi quella di default quando l’autenticazione non
va a buon fine. Tuttavia qui c’è veramente poco da fare.

post '/auth/unauthenticated' do
 redirect '/'
end

E’ stato bello

L’ultima rotta che dobbiamo dare ai nostri utenti è quella per il logout
volontario.

get '/auth/logout' do
  env['warden'].raw_session.inspect
  env['warden'].logout
  flash[:success] = 'Successfully logged out'
  redirect '/'
end

Anche in questo caso ci affidiamo ad un metodo di default di Warden per il
logout.

Console

Come promesso ecco la bonus track. In Sinatra non
c’è come dicevamo, l’equivalente di rails console o della console di
padrino.
A volte, anzi sempre, è utile testare modelli, helper via
IRB. Per fare questo il
nostro script, che chiameremo /bin/console, non dovrà fare altro che
includere la nostra applicazione, app.rb, ed avviare IRB.

#!/usr/bin/env ruby

require 'irb'
require './app'

IRB.start
Kernel.exit(0)

Tutto qui? Sì, tutto qui.
Se lo confrontate con il config.ru, noterete che sono pressoché identici. La
differenza più importante è che, al posto di lanciare la nostra applicazione,
si lancierà IRB.

require './app'

run Unlock

Nel caso di config.ru più complessi e quindi applicazioni Sinatra con più
modelli, più controller, un mapping delle rotte più granulare la regola aurea
per creare un bin/console è quella di copiare il config.ru, eliminare l’ultima
parte del file ed avviare IRB dopo che sono state caricate tutte le dipendenze.
L’ultima riga, la Kernel.exit(0) ci assicura che non parta Sinatra una
volta usciti da IRB, facendo terminare correttamente lo script.

Off by one

Abbiamo quasi finito. Il nostro sistema ora permette di autenticare gli utenti
su active directory e gestire la loro sessione tramite Warden. Nella prossima
puntata inseririremo la protezione per il cross site request
forgery
ed un meccanismo per inserire
controlli per evitare l’immissione di password troppo semplici da parte dei
nostri utenti.

Enjoy it!

Tag:

Lascia un commento

Il tuo indirizzo email non sarà pubblicato.