web-dev-qa-db-fra.com

Qu'est-ce qu'un schéma d'authentification très simple pour Sinatra/Rack?

Je suis occupé à porter une très petite application Web d'ASP.NET MVC 2 vers Ruby/Sinatra.

Dans l'application MVC, FormsAuthentication.SetAuthCookie était utilisé pour définir un cookie persistant lorsque la connexion de l'utilisateur était correctement validée par rapport à la base de données.

Je me demandais quel serait l'équivalent de l'authentification par formulaires dans Sinatra? Tous les cadres d'authentification semblent très volumineux et ne correspondent pas vraiment à ce que je recherche.

37
AndrewVos

Voici un schéma d’authentification très simple pour Sinatra.

Je vais expliquer comment cela fonctionne ci-dessous.

class App < Sinatra::Base
  set :sessions => true

  register do
    def auth (type)
      condition do
        redirect "/login" unless send("is_#{type}?")
      end
    end
  end

  helpers do
    def is_user?
      @user != nil
    end
  end

  before do
    @user = User.get(session[:user_id])
  end

  get "/" do
    "Hello, anonymous."
  end

  get "/protected", :auth => :user do
    "Hello, #{@user.name}."
  end

  post "/login" do
    session[:user_id] = User.authenticate(params).id
  end

  get "/logout" do
    session[:user_id] = nil
  end
end

Pour tout itinéraire que vous souhaitez protéger, ajoutez-y la condition :auth => :user, comme dans l'exemple /protected ci-dessus. Cela appellera la méthode auth, qui ajoute une condition à la route via condition.

La condition appelle la méthode is_user?, définie comme aide. La méthode doit renvoyer true ou false selon que la session contient un identifiant de compte valide. (L'appel dynamique des assistants comme celui-ci facilite l'ajout d'autres types d'utilisateurs avec des privilèges différents.)

Enfin, le gestionnaire before définit une variable d’instance @user pour chaque demande, par exemple pour afficher le nom de l’utilisateur en haut de chaque page. Vous pouvez également utiliser l'assistant is_user? dans vos vues pour déterminer si l'utilisateur est connecté.

74
Todd Yandell

La réponse de Todd ne fonctionne pas pour moi, et j'ai trouvé une solution encore plus simple pour l'authentification simple et mortelle dans Sinatra's FAQ :

require 'rubygems'
require 'sinatra'

use Rack::Auth::Basic, "Restricted Area" do |username, password|
    [username, password] == ['admin', 'admin']  
end

get '/' do
    "You're welcome"
end

Je pensais que je le partagerais au cas où quelqu'un s'égarerait sur cette question et aurait besoin d'une solution non persistante.

27
Ralphleon

J'ai trouvé ce tutoriel et ce référentiel avec un exemple complet, cela fonctionne très bien pour moi

https://sklise.com/2013/03/08/sinatra-warden-auth/

https://github.com/sklise/sinatra-warden-example

5
xyz

J'ai utilisé la réponse acceptée pour une application qui ne contenait que 2 mots de passe, un pour les utilisateurs et un pour les administrateurs. Je viens de créer un formulaire de connexion qui prend un mot de passe (ou une épingle) et le compare à celui que j'avais défini dans les paramètres de sinatra (un pour l'administrateur, un pour l'utilisateur). Ensuite, je règle la session [: current_user] sur admin ou user en fonction du mot de passe que l'utilisateur a entré et autorisé en conséquence. Je n'avais même pas besoin d'un modèle d'utilisateur. Je devais faire quelque chose comme ça:

use Rack::Session::Cookie, :key => 'rack.session',
                       :domain => 'foo.com',
                       :path => '/',
                       :expire_after => 2592000, # In seconds
                       :secret => 'change_me'

Comme mentionné dans la documentation sinatra pour que la session persiste en chrome. Avec cela ajouté à mon fichier principal, ils persistent comme prévu.

1
Josh Hunter