简体   繁体   中英

What is a very simple authentication scheme for Sinatra/Rack

I am busy porting a very small web app from ASP.NET MVC 2 to Ruby/Sinatra.

In the MVC app, FormsAuthentication.SetAuthCookie was being used to set a persistent cookie when the users login was validated correctly against the database.

I was wondering what the equivalent of Forms Authentication would be in Sinatra? All the authentication frameworks seem very bulky and not really what I'm looking for.

Here is a very simple authentication scheme for Sinatra.

I'll explain how it works below.

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

For any route you want to protect, add the :auth => :user condition to it, as in the /protected example above. That will call the auth method, which adds a condition to the route via condition .

The condition calls the is_user? method, which has been defined as a helper. The method should return true or false depending on whether the session contains a valid account id. (Calling helpers dynamically like this makes it simple to add other types of users with different privileges.)

Finally, the before handler sets up a @user instance variable for every request for things like displaying the user's name at the top of each page. You can also use the is_user? helper in your views to determine if the user is logged in.

Todd's answer does not work for me, and I found an even simpler solution for one-off dead simple authentication in 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

I thought I would share it just in case anyone wandered this question and needed a non-persistent solution.

I' have found this tutorial and repository with a full example, its working fine for me

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

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

I used the accepted answer for an app that just had 2 passwords, one for users and one for admins. I just made a login form that takes a password(or pin) and compared that to one that I had set in sinatra's settings (one for admin, one for user). Then I set the session[:current_user] to either admin or user according to which password the user entered and authorized accordingly. I didn't even need a user model. I did have to do something like this:

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

As mentioned in the sinatra documentation to get the session to persist in chrome. With that added to my main file, they persist as expected.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM