본문으로 건너뛰기

Ruby on Rails 앱에서 Devise 및 CanCanCan을 이용한 인증 및 권한 부여 설정 튜토리얼 (Rails 8, Ruby 3.4)

Authentication with Devise and CanCanCan in Rails 8

작성자
발행일
2025년 05월 14일
https://hibbard.eu/authentication-with-devise-and-cancancan-in-rails/

핵심 요약

  • 1 Devise Gem을 활용하여 Ruby on Rails 8 애플리케이션에 사용자 인증 시스템(회원가입, 로그인, 세션 관리)을 효율적으로 구축하는 방법을 설명합니다.
  • 2 CanCanCan Gem을 사용하여 관리자, 판매자, 일반 사용자 등 역할 기반의 정교한 권한 부여 로직을 구현하고, 각 역할에 따른 리소스 접근 및 CRUD 작업을 제어하는 과정을 안내합니다.
  • 3 프로젝트 생성부터 UI 개선, 에러 처리, 사용자 관리 인터페이스 구축에 이르기까지 Devise와 CanCanCan을 연동하여 견고한 인증 및 권한 시스템을 완성하는 실용적인 튜토리얼입니다.

도입

본 튜토리얼은 Ruby on Rails 8 애플리케이션에서 Devise와 CanCanCan Gem을 활용하여 사용자 인증(authentication) 및 권한 부여(authorization) 시스템을 구축하는 방법을 다룹니다. Ruby 3.4 버전을 기반으로 로컬 환경에서 외부 인증 서비스 없이 모든 기능을 구현합니다. 가상의 온라인 상점 앱을 시나리오로 하여, 등록되지 않은 사용자, 일반 사용자, 판매자, 관리자 역할을 정의하고 각 역할에 따른 아이템, 사용자, 역할 리소스에 대한 접근 권한을 설정하는 과정을 상세히 설명합니다. 이 튜토리얼은 최신 Ruby 및 Rails 버전에 맞춰 2025년 6월 7일 업데이트되었습니다.

본 튜토리얼은 Ruby on Rails 8 환경에서 Devise와 CanCanCan을 활용한 인증 및 권한 부여 시스템 구축 과정을 다음과 같이 상세히 안내합니다.

1. 의존성 설치 및 프로젝트 초기화

  • Ruby 및 Rails 설치: rbenv를 사용하여 Ruby 3.4.4를 설치하고, 해당 Ruby 버전에 Rails 8.0.2를 전역으로 설치합니다.

  • Rails 프로젝트 생성: rails new store --skip-jbuilder 명령어로 새 Rails 앱을 생성하고, Item, User, Role 스캐폴드를 생성하여 기본 데이터베이스 구조를 마련합니다. 이때 price:decimal{5,2}belongs_to 관계를 정의합니다.

2. 스캐폴드 뷰 수정 및 스타일 적용

  • 생성된 스캐폴드 뷰에서 불필요한 notice 메시지를 제거하고, _item.html.erb, _form.html.erb, _user.html.erb, _form.html.erb 파일들을 수정하여 사용자 경험을 개선합니다. 특히 user_iduser.name으로 변경하고, role_id 필드를 collection_select로 대체하여 드롭다운 선택을 가능하게 합니다.

  • 프로젝트 저장소에서 제공된 CSS 스타일을 app/assets/stylesheets/application.css에 추가하여 기본적인 UI를 개선합니다.

3. Devise를 이용한 인증 구현

  • Devise 설치 및 설정: Gemfile에 Devise를 추가하고 bundle installrails g devise:install을 실행합니다. config/environments/development.rbdefault_url_options를 설정하고, config/routes.rb에 루트 경로를 지정합니다.

  • User 모델에 Devise 적용: rails g devise User 명령어로 User 모델에 Devise 인증 기능을 추가하고 마이그레이션을 실행합니다.

  • 애플리케이션 레이아웃 업데이트: app/views/layouts/application.html.erb 파일을 수정하여 로그인/로그아웃 링크, 사용자 정보, 관리자 내비게이션 바를 포함한 헤더를 추가합니다.

  • 컨트롤러 보호: ItemsController, RolesController, UsersControllerbefore_action :authenticate_user!를 추가하여 로그인하지 않은 사용자의 접근을 제한합니다.

  • 초기 데이터 시딩: db/seeds.rbRegular, Seller, Admin 역할을 가진 사용자 및 아이템 데이터를 추가하고 rails db:seed를 실행합니다.

  • Devise 모듈 이해: User 모델에 포함된 Devise 모듈(:database_authenticatable, :registerable, :recoverable, :rememberable, :validatable, :trackable)의 역할과 커스터마이징 가능성을 설명합니다.

4. Devise 커스터마이징 및 사용자 관리

  • 관리자 네임스페이스: config/routes.rb를 수정하여 /admin 스코프 내에 사용자 관리 리소스를 정의하여 사용자 등록 경로와의 충돌을 방지합니다.

  • User-Item 관계: User 모델에 has_many :items, dependent: :destroy를 추가하고, ItemsControllercreate 액션에서 current_user를 아이템에 할당합니다.

  • Devise 뷰 커스터마이징: rails g devise:views 명령어로 Devise 뷰 파일을 복사한 후, new.html.erbedit.html.erbname 필드를 추가합니다. ApplicationController에서 configure_permitted_parameters를 통해 name 파라미터를 허용합니다.

  • 기본 역할 자동 할당: User 모델에 before_validation :assign_role 콜백을 추가하여 신규 사용자에게 기본 Regular 역할을 자동으로 부여합니다.

  • 관리자 사용자 생성/수정: 관리자 인터페이스를 통해 사용자 이메일, 비밀번호를 관리할 수 있도록 _user.html.erb_form.html.erb를 수정합니다. UsersController에서 update_without_password 메서드를 활용하여 비밀번호 변경 없이 사용자 정보를 업데이트할 수 있도록 구현합니다.

  • Trackable 모듈 활성화: User 모델에 :trackable 모듈을 추가하고 마이그레이션을 통해 관련 컬럼(sign_in_count, current_sign_in_at 등)을 추가하여 사용자 로그인 정보를 추적합니다. users/show.html.erbUsersController에 해당 정보를 표시합니다.

  • Role-User 관계: Role 모델에 has_many :users, dependent: :restrict_with_exception을 추가하고, roles/show.html.erbRolesController에 특정 역할에 연결된 사용자 목록을 표시합니다.

5. CanCanCan을 이용한 권한 부여

  • CanCanCan 설치 및 Ability 클래스 정의: Gemfile에 CanCanCan을 추가하고 rails g cancan:ability를 실행합니다. app/models/ability.rb 파일에서 initialize(user) 메서드를 수정하여 관리자(admin?), 판매자(seller?), 일반 사용자(regular?) 역할에 따른 can :manage, :all, can :read, Item, can :create, Item, can :update, Item do |item| ... end, can :destroy, Item do |item| ... end 등의 권한 규칙을 정의합니다.

  • User 모델에 역할 메서드 추가: User 모델에 admin?, seller?, regular? 메서드를 추가하여 사용자의 역할을 쉽게 확인할 수 있도록 합니다.

  • 컨트롤러에 권한 적용: ItemsController, UsersController, RolesController 상단에 load_and_authorize_resource를 추가하여 리소스 로딩과 권한 검사를 자동으로 처리하고, 불필요한 set_ 메서드 호출을 제거합니다.

  • 에러 처리: ApplicationControllerrescue_from CanCan::AccessDenied 블록을 추가하여 권한 없는 접근 시 flash 메시지와 함께 루트 경로로 리다이렉트되도록 합니다.

  • 뷰에서 권한 조건부 렌더링: items/show.html.erbitems/index.html.erb에서 can? :action, @resource 헬퍼를 사용하여 사용자 권한에 따라 링크 및 버튼을 조건부로 표시합니다.

6. 마무리 및 UI 개선

  • 관리자 내비게이션 조건부 표시: application.html.erb에서 관리자 내비게이션을 current_user&.admin? 조건에 따라 표시합니다.

  • 플래시 메시지 자동 사라짐: Stimulus 컨트롤러(flash_controller.js)를 생성하여 플래시 메시지가 3.5초 후 자동으로 사라지도록 구현하고, application.html.erb의 플래시 메시지에 data-controller="flash" 속성을 추가합니다.

  • 환영 페이지 설정: WelcomeControllerindex 뷰를 생성하고, config/routes.rb에서 authenticated :user 블록을 활용하여 로그인한 사용자는 `items

index로, 로그인하지 않은 사용자는 welcome

index`로 리다이렉트되도록 설정합니다.

이러한 단계를 통해 Rails 앱에서 사용자 인증 및 역할 기반 권한 부여를 완벽하게 구현하고, 사용자 친화적인 인터페이스를 제공하는 방법을 학습합니다.

결론

본 튜토리얼은 Ruby on Rails 8 환경에서 Devise와 CanCanCan을 활용하여 강력하고 유연한 인증 및 권한 부여 시스템을 구축하는 과정을 성공적으로 시연했습니다. Devise의 모듈화된 접근 방식과 CanCanCan의 역할 기반 권한 관리 기능을 통해 최소한의 코드로 복잡한 보안 요구사항을 충족할 수 있음을 확인했습니다. 초기 프로젝트 설정부터 세부적인 뷰 커스터마이징, 사용자 관리, 그리고 최종적인 UI 개선에 이르기까지 실질적인 개발 흐름을 제시함으로써, 개발자들이 실제 애플리케이션에 이러한 기능을 효과적으로 통합할 수 있는 기반을 제공합니다. 이 튜토리얼의 전체 코드는 GitHub 저장소에서 확인할 수 있으며, 본 가이드가 Rails 개발자들에게 유용한 자료가 되기를 기대합니다.

댓글0

댓글 작성

댓글 삭제 시 비밀번호가 필요합니다.

이미 계정이 있으신가요? 로그인 후 댓글을 작성하세요.

0/1000
정중하고 건설적인 댓글을 작성해 주세요.