18. 인증된 회원만 접근 가능하도록 만들기

2020. 6. 30. 16:18Rails 5 on aws c9

18. 인증된 회원만 접근 가능하도록 만들기

contact list에 로그인된 유저만 접근 가능하게 만들어보자

ApplicationController에 athenticate라는 함수를 작성하자

class ApplicationController < ActionController::Base
  protect_from_forgery with: :exception
  include SessionsHelper

  def authenticate
    #if문을 뒤에 쓸수도 있다. 유저가 로그인이 안되었으면 로그인창으로 이동 
    # redirect_to new_session_path if !user_signed_in? 는 다음과 같다 
    redirect_to new_session_path unless user_signed_in?
  end
end

ApplicationController에 넣어두면 다른 모든 상속받는 컨트롤러에서 사용 가능하다

이제 ContactsController를 수정해보자

class ContactsController < ApplicationController
  # before_action :authenticate == 이 컨트롤러의 모든 액션 실행전에 authenticate 함수 실행
  # 뒤에 only: [:index] 붙으면 index 액션만
  before_action :authenticate, only: [:index]

  def index
    @all_contacts = Contact.all #배열 형태로 저장된다
  end

  def new
  end

  def create
    @name = params[:name]
    @email = params[:email]
    @content = params[:content]
    new_contact = Contact.new(name: @name, email: @email, content: @content)
    if new_contact.save #저장 결과를 bool값으로 리턴한다
      redirect_to contacts_path #/contacts/index에서 변경:세이브가 완료되면 컨텍츠들의 리스트를 보는 뷰로 간다
    else
      redirect_to new_contact_path #/contacts/new에서 변경:세이브가 실패하면 폼으로 다시 돌아간다
    end
  end
end

로그아웃 상태에서 컨택트를 작성하면 다음과 같은 화면이 뜬다(로그인 하라는)

 

지금은 회원가입하면 모두 Contact를 볼 수 있다.

이제는 admin만 볼 수 있게 만들어보자.

ubuntu:~/environment/hello_world (master) $ rails g migration AddUserToAdmin

Running via Spring preloader in process 17792
      invoke  active_record
      create    db/migrate/20200613092859_add_user_to_admin.rb

db/migrate/20200613092859_add_user_to_admin.rb 폴더로 가서

class AddUserToAdmin < ActiveRecord::Migration[5.0]
  def change
    add_column :users, :admin, :boolean, default: false
  end
end

로 변경하고, rake db:migrate 실행하면 잘 추가된걸 볼 수 있다.

ubuntu:~/environment/hello_world (master) $ rake db:migrate== 20200613094139 AddUserToAdmin: migrating ==================================
-- add_column(:users, :admin, :boolean, {:default=>false})
   -> 0.0053s
== 20200613094139 AddUserToAdmin: migrated (0.0063s) =========================

이제 관리자만 접근할 수 있게 컨트롤러에 코드를 추가해주자.

class ApplicationController < ActionController::Base
  protect_from_forgery with: :exception
  include SessionsHelper

  def authenticate
    #if문을 뒤에 쓸수도 있다. 유저가 로그인이 안되었으면 로그인창으로 이동 
    # redirect_to new_session_path if !user_signed_in? 는 다음과 같다 
    redirect_to new_session_path unless user_signed_in?
  end

  def authenticate_admin
    unless current_user.admin
      flash[:alert] = 'no admin'
      redirect_to '/'
    end
  end
end

application.html.erb 수정, (그리고 sessions/new.html.erb에서 <%= flash[:alert] %> 는 삭제해주자.)

<!DOCTYPE html>
<html>
  ...

  <body>
    ....
    <%= flash[:alert] %>
    <%= yield %>
  </body>
</html>

그리고 ContactsController를 수정해보자

class ContactsController < ApplicationController
  # before_action :authenticate == 이 컨트롤러의 모든 액션 실행전에 authenticate 함수 실행
  # 뒤에 only: [:index] 붙으면 index 액션만
  before_action :authenticate, only: [:index]
  before_action :authenticate_admin, only: [:index]

  def index
    @all_contacts = Contact.all #배열 형태로 저장된다
  end

  def new
  end

  def create
    @name = params[:name]
    @email = params[:email]
    @content = params[:content]
    new_contact = Contact.new(name: @name, email: @email, content: @content)
    if new_contact.save #저장 결과를 bool값으로 리턴한다
      redirect_to contacts_path #/contacts/index에서 변경:세이브가 완료되면 컨텍츠들의 리스트를 보는 뷰로 간다
    else
      redirect_to new_contact_path #/contacts/new에서 변경:세이브가 실패하면 폼으로 다시 돌아간다
    end
  end
end

contacts 에 접근하면, 이제 admin 이 없다고 뜬다

이제 admin 아이디에 권한을 줘보자.

ubuntu:~/environment/hello_world (master) $ rails c
Running via Spring preloader in process 18940
Loading development environment (Rails 5.0.7.2)

2.6.3 :003 > user = User.last
  User Load (0.1ms)  SELECT  "users".* FROM "users" ORDER BY "users"."id" DESC LIMIT ?  [["LIMIT", 1]]
 => #<User id: 3, name: "admin", email: "admin@naver.com", password_digest: "$2a$12$AmHPKB0qNKxVrDc9Dbe9uu6ZEA56vgdhaeQggSCNQ1R...", created_at: "2020-06-13 09:54:42", updated_at: "2020-06-13 09:54:42", admin: false> 

2.6.3 :004 > user.admin = true
 => true 

2.6.3 :006 > user.save
   (0.1ms)  begin transaction
  SQL (1.9ms)  UPDATE "users" SET "updated_at" = ?, "admin" = ? WHERE "users"."id" = ?  [["updated_at", "2020-06-13 09:56:25.285815"], ["admin", "t"], ["id", 3]]
   (5.4ms)  commit transaction
 => true

admin으로 로그인하면 잘 된다

관리자 권한이 있을때만 contacts 리스트를 보는 메뉴가 생기도록 해보자.

<!DOCTYPE html>
<html>
  <head>
    <title>HelloWorld</title>
    <%= csrf_meta_tags %>

    <%= stylesheet_link_tag    'application', media: 'all', 'data-turbolinks-track': 'reload' %>
    <%= javascript_include_tag 'application', 'data-turbolinks-track': 'reload' %>
  </head>

  <body>
    <div id="global-header">
      <div class="container">
        <div class="logo">My Profile</div>
        <ul class="menu">
          <a href="/">
            <li class="item">Home</li>
          </a>
          <!--link_to 헬퍼를 이용 해보자-->
          <!--<a href="/contacts/new">-->
          <%= link_to new_contact_path do %>
            <li class="item">Contact</li>
          <!--</a>-->
          <% end %>
          <% if user_signed_in? %>
            <li class="item"><%= current_user.name %></li>
            <!-- rake routes하면 session DELETE /sessions/:id(.:format) sessions#destroy -->
            <li class="item"><%= link_to 'Sign out', session_path(current_user), method: 'delete' %></li>
            ***<% if current_user.admin %>
              <li class="item"><%= link_to 'Contacts list', contacts_path %></li>
            <% end %>***
          <% else %>
            <li class="item"><%= link_to 'Sign in', new_session_path %></li>
            <li class="item"><%= link_to 'Sign up', new_user_path %></li>
          <% end %>
        </ul>
      </div>
    </div>
    <%= flash[:alert] %>
    <%= yield %>
  </body>
</html>