#250 Authentication from Scratch (revised)
Feb 25, 2012 | 13 minutes | Authentication
Simple password authentication is easy to do with has_secure_password. Here you will learn how to make a complete Sign Up, Log In, and Log Out process as well as restrict access to certain actions.
- Download:
- source codeProject Files in Zip (102 KB)
- mp4Full Size H.264 Video (25 MB)
- m4vSmaller H.264 Video (14.4 MB)
- webmFull Size VP8 Video (17.5 MB)
- ogvFull Size Theora Video (30.7 MB)
Resources
terminal
rails g resource user email password_digest rake db:migrate rails g controller sessions new
Gemfile
gem 'bcrypt-ruby', '~> 3.0.0'
config/routes.rb
get 'signup', to: 'users#new', as: 'signup' get 'login', to: 'sessions#new', as: 'login' get 'logout', to: 'sessions#destroy', as: 'logout' resources :users resources :sessions
models/user.rb
has_secure_password attr_accessible :email, :password, :password_confirmation validates_uniqueness_of :email
users_controller.rb
def new @user = User.new end def create @user = User.new(params[:user]) if @user.save session[:user_id] = @user.id redirect_to root_url, notice: "Thank you for signing up!" else render "new" end end
sessions_controller.rb
def new end def create user = User.find_by_email(params[:email]) if user && user.authenticate(params[:password]) session[:user_id] = user.id redirect_to root_url, notice: "Logged in!" else flash.now.alert = "Email or password is invalid" render "new" end end def destroy session[:user_id] = nil redirect_to root_url, notice: "Logged out!" end
application_controller.rb
private def current_user @current_user ||= User.find(session[:user_id]) if session[:user_id] end helper_method :current_user def authorize redirect_to login_url, alert: "Not authorized" if current_user.nil? end
articles_controller.rb
before_filter :authorize, only: [:edit, :update]
users/new.html.erb
<h1>Sign Up</h1> <%= form_for @user do |f| %> <% if @user.errors.any? %> <div class="error_messages"> <h2>Form is invalid</h2> <ul> <% @user.errors.full_messages.each do |message| %> <li><%= message %></li> <% end %> </ul> </div> <% end %> <div class="field"> <%= f.label :email %><br /> <%= f.text_field :email %> </div> <div class="field"> <%= f.label :password %><br /> <%= f.password_field :password %> </div> <div class="field"> <%= f.label :password_confirmation %><br /> <%= f.password_field :password_confirmation %> </div> <div class="actions"><%= f.submit "Sign Up" %></div> <% end %>
sessions/new.html.erb
<h1>Log In</h1> <%= form_tag sessions_path do %> <div class="field"> <%= label_tag :email %><br /> <%= text_field_tag :email, params[:email] %> </div> <div class="field"> <%= label_tag :password %><br /> <%= password_field_tag :password %> </div> <div class="actions"><%= submit_tag "Log In" %></div> <% end %>
layouts/application.html.erb
<% if current_user %> Logged in as <%= current_user.email %>. <%= link_to "Log Out", logout_path %> <% else %> <%= link_to "Sign Up", signup_path %> or <%= link_to "Log In", login_path %> <% end %>