Authentication

회원가입 및 권한부여는 어떤 프레임워크를 사용하던간에 꼭 튜토리얼에 존재하는 웹개발에서 가장 중요한 부분중 하나이다. devise만으로도 모든기능을 구현할 수 있지만, 다른 라이브러리들을 추가하면 좀 더 손쉽게 가능해진다.

목차

  • 회원가입 (devise)
  • 권한부여 및 접근제어 (cancancan, rolify)

회원가입

Devise 설치

Gemfile에 젬을 추가한뒤 bundle install

#Gemfile
gem 'devise'
gem 'devise-i18n'

devise 명령어를 입력해 설치하고, user모델을 생성해준다.

rails g devise:install
rails g devise user

routes.rb에 라우트가 추가된걸 볼 수 있다.

devise_for :users

config/appliaction.rb에서 지역을 ko로바꿔준다.

config.i18n.default_locale = :ko

rails g devise:view명령어로 devise 뷰파일들을 생성할 수 있다. 심볼은 영어로 되어있지만 값은 한글로 되어있으니 당황할 필요 없다. 심볼의 대응값들을 확인하고 싶다면 rails g devise:i18n:locale ko명령어로 yml파일을 생성할 수 있다. config/locales 디렉토리에 있고 수정시 서버를 재시작해야한다.

참고

권한부여 및 접근제어

cancancan & rolify 설치

devise 만을 사용할 때에는 edit나 update같은 action을 다룰때 작성자의 id와 매칭해서 수정가능 여부를 확인한다. 또 권한에 대한 model을 만들어 특정 권한을 갖고있지 않으면 접근을 할 수 없게 만들었는데, 권한을 가진 직책(자격)들이 세부화 될수록 조금 복잡해지는 경향이 있다.

이때 cancancan과 rolify 라이브러리를 사용하면 손쉽게 권한관련 기능을 만들어 낼 수 있다.

gem 'cancancan'
gem 'rolify'

cancancan 명령어를 사용해 사용자의 권한을 정의해줄 Ability클래스를 생성한다.

rails generate cancan:ability

rolify 명령어로 Role(직책)을 사용자(user) 모델과 엮어 줄 것이다.

rails g rolify Role User

모델 디렉토리에서 user모델을 확인해보면 상단에 rolify가 추가되어있는것을 확인할 수 있고, role모델에서는 has_and_belongs_to_many :users, :join_table => :users_roles로 user모델과와 관계설정이 되어있는것을 확인할 수 있다. 과정이 끝나면 rake db:migrate해준다.

역할에 권한부여하기

레일즈 콘솔 rails c 로 들어가 미리 만들어둔 유저에 역할을 추가해준다.

user = User.find(1)
user.add_role = "admin"

user = User.find(2)
user.add_role = "newbie"

모델디렉토리에 ablity.rb를 아래와 같이 수정한다. (주석처리 되어있다.)

class Ability
  include CanCan::Ability

  def initialize(user)
    # Define abilities for the passed in user here. For example:
    #
  user ||= User.new # guest user (not logged in)

  if user.has_role? :admin
    can :manage, :all
  elsif user.has_role? :newbie
    can [:read, :create], :all
    can [:update, :destroy], Post, user_id: user.id
  else
    can :read, :all
  end

  #.....

만약 admin이라는 역할을 가지고 있다면 모든 권한을 갖고, newbie역할은 읽고 쓰는것은 자유롭지만, 수정과 삭제는 본인의 게시물만 가능하다. (has_role?rolify의 메소드이다. ) 이때 지정해준 액션들은 cancancan이 자동으로 체크하여 컨트롤러의 액션들과 매칭해준다. 자세한 내용은 링크를 참고하자.

역할별로 사용자들이 올바른 권한을 갖고있는지 확인해보자.

user = User.find(1)
admin = Ability.new(user)
# <Ability:0x00000002f8e998 @rules=[#<CanCan::Rule:0x00000004aedfe0 @match_all=false, 
# @base_behavior=true, @actions=[:manage], @subjects=[:all], @conditions={}, @block=nil>],
# @rules_index={:all=>[0]}> 

admin.can? :manage, :all #  => true

user2 = User.find(2)
newbie = Ability.new(user2)

# <Ability:0x00000004a1a0a0 @rules=[#<CanCan::Rule:0x000000049a5390 @match_all=false, @base_behavior=true, 
# @actions=[:read, :create], @subjects=[:all], @conditions={}, @block=nil>, 
# <CanCan::Rule:0x0000000491dfa8 @match_all=false, @base_behavior=true, @actions=[:update, :destroy], 
# @subjects=[Post(id: integer, user_id: integer, title: string, content: string, created_at: datetime, 
# updated_at: datetime)], 
# @conditions={:user_id=>2}, @block=nil>], 
# @rules_index={:all=>[0], Post(id: integer, user_id: integer, title: string, content: string, 
# created_at: datetime, updated_at: datetime)=>[1]}>

이제 posts_controller.rb 상단에 load_and_authorize_resource를 넣어주면 권한이 없는 action에 접근했을 때 예외(에러)가 발생한다.

class PostsController < ApplicationController
  before_action :set_post, only: [:show, :edit, :update, :destroy]
  load_and_authorize_resource 

  #...

예외가 발생하면 home화면으로 이동하도록 핸들링 해주기 위해, application_controller.rb에 아래와 같이 추가해 준다.

rescue_from CanCan::AccessDenied do |exception|
  redirect_to root_url, :alert => exception.message
end

참고

  • rolify
    • wiki와 tutorial이 아주 쉽게 잘 나와 있다.
  • cancancan
    • wiki에서 Controller Authorization Example 를 참고하자.

results matching ""

    No results matching ""