Skip to content

Instantly share code, notes, and snippets.

@ryanb
Created January 19, 2011 19:31
Show Gist options
  • Save ryanb/786693 to your computer and use it in GitHub Desktop.
Save ryanb/786693 to your computer and use it in GitHub Desktop.
Example of very simple password authentication.
<!-- layout file -->
<% if current_user %>
Welcome <%= current_user.username %>. Not you? <%= link_to "Log out", logout_path %>
<% else %>
<%= link_to "Sign up", signup_path %> or <%= link_to "log in", login_path %>.
<% end %>
class ApplicationController < ActionController::Base
helper_method, :current_user
private
def current_user
@current_user ||= User.find(session[:user_id]) if session[:user_id]
end
# call this as a before_filter to require them to be logged in
def login_required
if current_user.nil?
redirect_to login_url, :alert => "You must first log in or sign up before accessing this page."
end
end
end
<!-- login form under views/sessions/new.html.erb -->
<%= form_tag sessions_path do %>
<p>
<%= label_tag :login, "Username or Email Address" %><br />
<%= text_field_tag :login, params[:login] %>
</p>
<p>
<%= label_tag :password %><br />
<%= password_field_tag :password %>
</p>
<p><%= submit_tag "Log in" %></p>
<% end %>
match 'signup' => 'users#new', :as => :signup
match 'logout' => 'sessions#destroy', :as => :logout
match 'login' => 'sessions#new', :as => :login
resources :sessions
resources :users
class SessionsController < ApplicationController
def new
end
def create
user = User.authenticate(params[:login], params[:password])
if user
session[:user_id] = user.id
redirect_to root_url, :notice => "Logged in successfully."
else
flash.now[:alert] = "Invalid login or password."
render :action => 'new'
end
end
def destroy
session[:user_id] = nil
redirect_to root_url, :notice => "You have been logged out."
end
end
# run: rails g model User username:string email:string password_hash:string password_salt:string
class User < ActiveRecord::Base
# new columns need to be added here to be writable through mass assignment
attr_accessible :username, :email, :password, :password_confirmation
attr_accessor :password
before_save :prepare_password
validates_presence_of :password, :on => :create
validates_confirmation_of :password
validates_length_of :password, :minimum => 4, :allow_blank => true
# you may want to add validations to email/username here too
# login can be either username or email address
def self.authenticate(login, pass)
user = find_by_username(login) || find_by_email(login)
return user if user && user.matching_password?(pass)
end
def matching_password?(pass)
self.password_hash == encrypt_password(pass)
end
private
def prepare_password
unless password.blank?
self.password_salt = BCrypt::Engine.generate_salt
self.password_hash = encrypt_password(password)
end
end
def encrypt_password(pass)
BCrypt::Engine.hash_secret(pass, password_salt) # add to Gemfile: gem "bcrypt-ruby", :require => "bcrypt"
end
end
@ryanb
Copy link
Author

ryanb commented Jan 19, 2011

This is a simplified version of the nifty:authentication generator in Nifty Generators. I did not include the Users controller to handle registration/editing but that is fairly straight forward.

@ryanb
Copy link
Author

ryanb commented Jan 19, 2011

I highly recommend adding OmniAuth in here as well. That is simple to do as shown here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment