2010-08-24 11 views
37

Estoy ocupado portando una aplicación web muy pequeña desde ASP.NET MVC 2 a Ruby/Sinatra.Qué es un esquema de autenticación muy simple para Sinatra/Rack

En la aplicación MVC, FormsAuthentication.SetAuthCookie se utilizaba para establecer una cookie persistente cuando el inicio de sesión de los usuarios se validaba correctamente en la base de datos.

Me preguntaba cuál sería el equivalente de Autenticación de formularios en Sinatra? Todos los marcos de autenticación parecen muy voluminosos y no son realmente lo que estoy buscando.

+3

Así que, aunque no voy a fingir que esto responde a su pregunta, voy a señalar que es intrínsecamente peligroso diseñar y desarrollar su propio esquema de autenticación. Hay muchos "hackers" que comienzan a babear cuando encuentran este tipo de cosas. Es mejor encontrar herramientas establecidas y comprobadas para hacer esto.No es un problema nuevo y ya hay muchas soluciones aceptables. – jaydel

+0

Utilice la gema bcrypt. Puede generar hashes crípticos para contraseñas y si un hackie accedió a su base de datos, todo lo que obtienen son los hashes y no deberían funcionar para las contraseñas. En otras palabras, mantenlo de una manera. Verá mucho en bcrypt-ruby, pero ahora solo está en formato binario y es un tipo de extensión C, por lo que deberá compilarlo en Windows con algunas herramientas de desarrollo. Tienes razón, son voluminosos. https://sideprojectsoftware.com/blog/2015/02/22/sinatra-authentication debería ayudar. –

Respuesta

73

Aquí hay un esquema de autenticación muy simple para Sinatra.

Explicaré cómo funciona a continuación.

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 

Para cualquier ruta que desea proteger, agregue la condición :auth => :user a ella, como en el ejemplo anterior /protected. Eso llamará al método auth, que agrega una condición a la ruta a través del condition.

La condición llama al método is_user?, que se ha definido como un ayudante. El método debe devolver verdadero o falso dependiendo de si la sesión contiene una identificación de cuenta válida. (Llamando ayudantes dinámicamente como esto hace que sea sencillo para añadir otros tipos de usuarios con diferentes privilegios.)

Por último, el manejador de before establece una variable @user instancia para cada solicitud de cosas como la que muestra el nombre del usuario en la parte superior de cada página. También puedes utilizar el helper is_user? en sus puntos de vista para determinar si el usuario se registra en

+0

En primer lugar, ¡gracias por una respuesta tan bien pensada! En segundo lugar, me olvido de mencionar, pero sería bueno si pudiera tener sesiones persistentes. Supongo que si hiciera algo como lo siguiente, ¿esto permitiría que la sesión sea persistente? Rack :: Session :: Cookie,: secret => "algún valor realmente único" ¿Hay algún problema de seguridad con este enfoque si ese es el caso? – AndrewVos

+0

hermosa, una oportunidad de usar más de la encantadora DSL de Sinatra :) –

+0

pero donde están almacenadas las credenciales de un usuario (nombre de usuario y contraseña)? ¡¿cómo podemos crear una cuenta de usuario para que él/ella pueda autonectarse !!! – Hanynowsky

27

respuesta de Todd no funciona para mí, y me encontré con una solución aún más simple de una sola vez la autenticación simple muerto en 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 

Pensé que podría compartirlo en caso de que alguien divagara esta pregunta y necesitara una solución no persistente.

+0

¡Es increíble, muchas gracias por compartir! –

+2

La respuesta de Todd no funciona tal como está, porque no está completa, no porque sea incorrecta. Por el contrario, es una solución bastante sofisticada y bien pensada, simplemente carece de un 'App.run!' Al final y, por supuesto, de la implementación real de la clase 'User' (responsable de la administración de credenciales) – p4010

1

utilicé la respuesta aceptada para una aplicación que acaba de tener 2 contraseñas, uno para usuarios y otro para administradores. Acabo de crear un formulario de inicio de sesión que toma una contraseña (o un pin) y la comparé con una que había establecido en la configuración de sinatra (una para el administrador y otra para el usuario). Luego configuré la sesión [: usuario_actual] para administrador o usuario según la contraseña que el usuario ingresó y autorizó en consecuencia. Ni siquiera necesito un modelo de usuario. Yo tenía que hacer algo como esto:

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

Como se mencionó en la sinatra documentation para obtener la sesión de persistir en cromo. Con eso agregado a mi archivo principal, persisten como se esperaba.

Cuestiones relacionadas