Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Simple authentication for small Rails apps without magic #10

Open
blackchestnut opened this issue Nov 26, 2016 · 0 comments
Open

Simple authentication for small Rails apps without magic #10

blackchestnut opened this issue Nov 26, 2016 · 0 comments

Comments

@blackchestnut
Copy link
Owner

blackchestnut commented Nov 26, 2016

Simple authentication with password

Dependencies

gem 'bcrypt'
gem 'ulid'

Create user model

r g model User email crypted_password token

class CreateUsers < ActiveRecord::Migration[5.0]
  def change
    create_table :users do |t|
      t.string :email
      t.string :crypted_password
      t.string :token

      t.timestamps
    end

    add_index :users, :email, unique: true
    add_index :users, :token, unique: true
  end
end
# app/models/user.rub

require 'bcrypt'
require 'ulid'

class User < ApplicationRecord
  include BCrypt
  before_create :generate_token

  validates :email, presence: true
  validates :crypted_password, presence: true

  def password
    @password ||= Password.new(crypted_password)
  end

  def password=(new_password)
    @password = Password.create(new_password)
    self.crypted_password = @password
  end

private

  def generate_token
    self.token = ULID.generate
  end
end

Add methods to the ApplicationController

# app/controllers/application_controller.rb

class ApplicationController < ActionController::Base
  # ...

  helper_method :token, :current_user, :signed_in?

  def current_user
    @current_user ||= User.find_by(token: token)
  end

  def signed_in?
    current_user.present?
  end

  def token
    params_token || session_token
  end

private

  def session_token
    session[:token]
  end

  def params_token
    params[:token]
  end

  def set_session_token(token)
    session[:token] = token
  end
end

Sign Up controller

r g controller Users new

# app/controllers/users_controller.rb

class UsersControllerController < ApplicationController
  skip_before_action :verify_authenticity_token, only: [:create]

  def new
  end

  def create
    @user = User.build(user_create_params)

    if @user.save?
      set_session_token(@user.token)
      redirect_to root_url(notice: 'Вы успешно зарегистировались')
    else
      render :new
    end
  end

private

  def user_create_params
    params.require(:user).permit(:email)
  end
end

Sign In controller

r g controller Sessions new

# app/controllers/sessions_controller.rb

class SessionsControllerController < ApplicationController
  skip_before_action :verify_authenticity_token, only: [:create]

  def new
    @user = User.new
  end

  def create
    @user = find_user

    if @user.present?
      set_session_token(@user.token)
      redirect_to root_url notice: 'Вы успешно вошли на сайт'
    else
      render :new
    end
  end

  def destroy
    set_session_token(nil)
    redirect_to root_url
  end

private

  def create_sessions_params
    params.require(:user).permit(:email, :password)
  end

  def find_user
    user = User.find_by(email: create_sessions_params[:email])
    return nil if user.nil?
    return nil if user.password != create_sessions_params[:password]

    user
  end
end

Routes

# config/routes.rb

Rails.application.routes.draw do
  resources :users, only: [:new, :create]
  resource :sessions, only: [:new, :create, :destroy]

  scope '(:token)' do
    # ...
  end
end
@blackchestnut blackchestnut changed the title Simple authentication for Rails small apps without magic Simple authentication for small Rails apps without magic Nov 26, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant