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