#!/user/bin/env ruby require 'bundler/inline' gemfile(true) do source 'https://rubygems.org' gem 'sinatra', '~> 1.4' gem 'bcrypt', '~> 3.1' end require 'sinatra/base' require 'bcrypt' def hash_password(password) BCrypt::Password.create(password).to_s end def test_password(password, hash) BCrypt::Password.new(hash) == password end User = Struct.new(:id, :username, :password_hash) USERS = [ User.new(1, 'bob', hash_password('the builder')), User.new(2, 'sally', hash_password('go round the sun')), ] class AuthExample < Sinatra::Base enable :inline_templates enable :sessions get '/' do if current_user erb :home else redirect '/sign_in' end end get '/sign_in' do erb :sign_in end post '/sign_in' do user = USERS.find { |u| u.username == params[:username] } if user && test_password(params[:password], user.password_hash) session.clear session[:user_id] = user.id redirect '/' else @error = 'Username or password was incorrect' erb :sign_in end end post '/create_user' do USERS << User.new( USERS.size + 1, #id params[:username], #username hash_password(params[:password]) #password_hash ) redirect '/' end post '/sign_out' do session.clear redirect '/sign_in' end helpers do def current_user if session[:user_id] USERS.find { |u| u.id == session[:user_id] } else nil end end end run! end __END__ @@ sign_in

Sign in

<% if @error %>

<%= @error %>

<% end %>
@@ home

Home

Hello, <%= current_user.username %>.

There are <%= USERS.size %> users registered:

Create New User

@@ layout Simple Authentication Example <%= yield %>