Computer >> 컴퓨터 >  >> 프로그래밍 >> Ruby

Ruby 인증 마스터하기:Pundit과 CanCanCan

오늘날 많은 웹 애플리케이션에는 홈페이지와 같이 공개적으로 사용할 수 있는 페이지와 사용자가 액세스하려면 로그인해야 하는 보다 안전한 페이지가 포함됩니다. 사용자 등록, 로그인, 사용자 세션 상태 추적 과정을 '인증'이라고 합니다.

동시에 로그인한 사용자를 처리할 때는 사용자 역할에 따라 사용할 수 있는 작업과 리소스를 분리해야 합니다. 예를 들어, "관리자"는 일반적으로 일반 사용자보다 더 많은 액세스 권한을 갖습니다. 이렇게 인증된 사용자 액세스를 분리하는 과정을 "인증"이라고 합니다.

이 게시물에서는 지금까지 Ruby에서 가장 인기 있는 두 가지 인증 라이브러리인 Pundit과 CanCanCan을 살펴보겠습니다.

뛰어들어 보세요!

설정 및 전제조건

이 기사에서는 사용자와 게시물이 포함된 간단한 Rails 7 앱을 사용하겠습니다. 사용자에게는 "편집자" 또는 "작가" 역할이 할당됩니다. 이러한 시나리오는 인증이 어떻게 작동하는지 보여주는 데 적합합니다.

다음을 사용하여 예시 앱의 코드 저장소를 확인하세요.

  • 전문가
  • 캔캔캔

이 글은 인증에 중점을 두고 있지만 인증이라는 동반 주제도 무시할 수 없습니다.

인증 설정에 대한 자세한 내용은 이 게시물의 범위를 벗어나므로 다루지 않겠습니다. Devise gem 문서의 설치 지침을 따를 수 있습니다. (저희는 Devise를 인증 gem과 페어링하겠습니다.)

한 가지 더 - Pundit을 사용하든 CanCanCan을 사용하든 앱의 사용자 역할을 정의하는 실제 작업은 인증 gem 중 하나를 설치할 때 자동으로 발생하지 않습니다. 수동으로 설정해야 합니다.

그렇게 합시다.

사용자 역할 정의

이미 Devise gem을 설치하고 사용자 모델을 설정했다고 가정해 보겠습니다. 다음 단계는 앱 사용자가 어떤 역할을 갖게 될지 결정하는 것입니다. 우리의 경우에는 다음과 같은 역할을 설정하겠습니다:

  • 작가 - 이 사용자 역할은 다음을 생성할 수 있습니다. , 수정 , 업데이트 , 삭제 자신의 게시물. 동시에 작가는 보기도 할 수 있습니다. 다른 작가의 게시물.
  • 편집자 - 편집자 역할을 가진 사용자는 수정할 수 있습니다. , 업데이트 , 보기 , 삭제 모든 사용자의 게시물을 작성할 수 있지만 만들 수는 없습니다. 자신의 게시물입니다.

사용자의 역할을 저장하는 열을 추가합니다(마이그레이션을 사용하여 사용자의 테이블 수정):

 

그런 다음 마이그레이션을 실행하세요:

 

그런 다음 방금 정의한 역할을 포함하도록 사용자 모델을 수정합니다.

 

이 작업을 진행하는 동안 Post를 설정해 보겠습니다. title 속성을 가진 모델 그리고 body , 게시물을 작성한 사용자에 대한 참조:

 

외래 키 user_id를 추가합니다. Post에 생성된 모든 게시물을 특정 사용자와 연결하는 모델입니다. 이미 Devise를 사용하여 사용자 인증을 설정했으므로 간단히 Posts의 생성 메소드를 수정하면 됩니다. user_id를 자동으로 설정하는 컨트롤러 현재 로그인한 사용자에게:

 

또한 User 모델을 수정하여 Post와 연결되어 있는지 확인할 수도 있습니다. 모델:

 

마지막으로 각각 다른 역할을 가진 일부 사용자로 데이터베이스를 시드해 보겠습니다.

 

그런 다음 데이터베이스를 시드하십시오:

 

지금까지 우리 앱에는 다음이 포함되었습니다:

  • Devise를 사용하여 인증을 설정합니다.
  • '작성자'와 '편집자'라는 두 가지 사용자 역할이 정의되었습니다.
  • Post 모델.

이로써 우리는 이제 Pundit과 제대로 협력하는 데 필요한 모든 것을 갖추게 되었습니다.

Pundit을 사용하여 Ruby 앱에서 인증

Pundit은 객체 지향 아키텍처와 일반 Ruby 클래스를 기반으로 구축된 인증 라이브러리입니다. 이는 앱에 맞게 확장할 수 있는 견고한 인증 레이어를 구축할 수 있는 도구를 제공합니다.

Ruby 앱에 Pundit 설치

앱의 Gemfile에 gem을 추가하세요:

 

그런 다음 터미널에서 다음 명령을 실행하세요:

 

또는 다음 명령을 실행하세요:

 

인증은 주로 컨트롤러 리소스에 대한 액세스를 허용하거나 거부하는 것을 다루기 때문에 다음 단계는 Pundit의 인증 모듈을 애플리케이션 컨트롤러에 추가하는 것입니다.

 

마지막으로 다른 모든 정책이 상속받을 기본 정책 클래스를 생성합니다.

 

다음과 같은 기본 정책 클래스가 제공됩니다:

 

이로써 Pundit은 이제 적절하게 설정되어 사용할 준비가 되었습니다. 또한 인증 및 사용자 역할이 설정되어 있습니다.

다음으로, 정책을 사용하여 각 사용자 역할이 Post에 액세스하는 방법을 정의하는 규칙을 구현하겠습니다. 자원.

Pundit 정책 구성

Pundit 용어에서 "정책"은 사용자 역할이 다양한 리소스와 상호 작용하는 방식에 대한 모든 규칙을 정의하는 일반 Ruby 클래스입니다.

이러한 정책에는 몇 가지 주목할만한 기능이 있습니다:

  • 각 정책은 기존 모델의 이름을 따서 명명되었으며 접미사에는 '정책'이라는 단어가 붙습니다. 예를 들어 Post 액세스되는 모델은 PostPolicy라고 합니다. .
  • attr_reader :두 개의 인수를 사용합니다. 첫 번째 인수는 user입니다. , 구체적으로 현재 로그인된 사용자 — current_user — 두 번째 인수는 인증 규칙을 정의하려는 모델입니다(이 경우 post). .
  • 인증 규칙이 설정된 리소스의 컨트롤러 메소드에 매핑되는 쿼리 메소드입니다. 조직적인 목적을 위해서는 app/policies 아래에 모든 정책을 두는 것이 가장 좋습니다. 폴더.

앱의 다양한 사용자 역할에 대해 정의해야 하는 액세스 규칙이 무엇인지 알고 있으므로 작성자 역할부터 시작하겠습니다.

역할에 대한 전문가 정책 정의

작가 역할을 사용하여 이 작업을 수행하는 방법을 살펴보겠습니다. 먼저 Post에 대한 작성자 역할의 액세스를 개략적으로 설명할 수 있습니다. 리소스는 다음과 같습니다:

  • 만들기 자신의 게시물
  • 수정 및 업데이트 자신의 게시물
  • 보기(또는 읽기) 자신의 게시물 및 다른 사용자의 게시물
  • 삭제 자신의 게시물

이를 염두에 두고 게시물 액세스 방법을 제어하는 새로운 정책을 생성하세요.

 

이는 이전에 생성한 기본 정책에서 상속된 다음과 같은 일반 정책 클래스를 제공합니다:

 

이제 그에 따라 작성자 역할에 대한 액세스 규칙을 추가해 보겠습니다(이러한 규칙은 기본 정책 클래스에서 상속된 모든 규칙보다 우선 적용됩니다).

 

여기에서는 게시물 컨트롤러의 해당 작업인 게시물을 생성, 편집, 업데이트 및 삭제할 때 작성자가 수행할 수 있는 작업을 정의합니다. 눈치채셨다면 이러한 규칙은 일반적으로 게시물에 적용되며 반드시 작성자 자신의 게시물에만 적용되는 것은 아닙니다(범위 섹션에서 이에 대해 알아보겠습니다).

지금은 이 정책을 어떻게 사용할 수 있는지 살펴보겠습니다.

Pundit에서 정책 사용

정책을 사용하려면 Pundit의 authorize로 전화하세요. 접근 규칙을 확인하려는 컨트롤러의 메소드에 메소드를 추가합니다. 관련 정책 클래스, 더 구체적으로 authorize가 있는 위치에 따라 호출되어야 하는 작업을 인스턴스화합니다. 메소드가 호출되었습니다.

예를 들어 authorize을 호출해 보겠습니다. 포스트 컨트롤러의 create 방법:

 

이를 테스트하려면 편집자로 로그인하여 create를 시도해 보세요. 게시물. 이렇게 하면 다음 오류가 발생합니다:

Ruby 인증 마스터하기:Pundit과 CanCanCan

이는 우리가 원하는 대로 이루어지지만 이러한 오류 페이지를 표시하는 것은 사용자 경험에 좋지 않습니다. 다음 섹션에서는 NotAuthorizedError을 구출하는 방법을 배우게 됩니다. 좀 더 사용자 친화적인 서비스를 제공하겠습니다.

Pundit의 NotAuthorizedError에서 구출하기

먼저 ApplicationController을 편집해야 합니다. 다음과 같습니다:

 

여기서는 기본적으로 Pundit에게 user_not_authorized을 사용하라고 지시하고 있습니다. NotAuthorizedError이 있을 때마다 메소드 제기됩니다. 승인되지 않은 사용자를 특정 페이지로 리디렉션하고 발생한 상황을 설명하는 관련 플래시 메시지도 제공합니다.

Ruby 인증 마스터하기:Pundit과 CanCanCan

이제 우리는 매우 일반화된 권한 사례를 처리할 수 있는 간단한 인증 시스템을 갖게 되었습니다.

하지만 좀 더 세분화된 권한을 원한다면 어떻게 될까요? 이를 위해서는 Pundit의 범위를 활용해야 합니다.

전문가의 범위

Pundit 범위는 ActiveRecord 범위와 유사합니다. 후자에서는 범위를 사용하여 특정 기준에 따라 레코드를 가져올 수 있습니다. 그러나 Pundit의 범위를 사용하면 설정한 특정 규칙에 따라 특정 리소스에 대한 액세스를 관리할 수 있습니다.

편집자가 "초안" 상태의 게시물을 보고 편집할 수 있는 동시에 작성자가 자신에게만 속한 게시물을 생성, 보기, 편집, 업데이트 및 삭제할 수 있도록 허용한다고 가정해 보겠습니다.

다음과 같이 게시물 정책을 편집하는 것부터 시작할 수 있습니다:

 

그런 다음 다음과 같이 게시물 컨트롤러의 리소스에 대한 액세스를 승인합니다:

 

물론, Pundit을 사용한 범위 지정은 우리가 보여준 것보다 훨씬 더 깊이 들어갈 수 있지만, 이 게시물에서는 그에 대해 그대로 두겠습니다. 원한다면 Pundit 문서를 확인하여 스코프를 보다 고급 방식으로 사용할 수 있는 방법을 알아보세요.

지금은 Rails의 강력한 매개변수로 라이브러리를 사용하는 방법을 살펴보겠습니다.

Rails의 강력한 매개변수와 함께 Pundit 사용

Pundit의 권한 부여 규칙과 Rails의 강력한 매개변수를 결합하면 리소스 속성에 대한 잠금 액세스를 달성할 수 있습니다. 편집자를 원한다고 가정해 보겠습니다. Post의 발췌 필드에 접근할 수 있는 유일한 사람 모델. 어떻게 하시겠습니까?

먼저 적절한 이름의 블록을 관련 정책에 추가하세요.

 

그런 다음 컨트롤러에서 허용된 params 블록을 수정합니다.

 

이로써 발췌가 완성되었습니다. 편집자만 사용할 수 있는 속성입니다.

이제 다른 인증 라이브러리인 CanCanCan을 살펴보겠습니다.

귀하의 Ruby 앱을 위한 CanCanCan 소개

CanCanCan은 "능력" 클래스를 사용하여 Rails 앱의 내용에 누가 액세스할 수 있는지 정의하는 인증 라이브러리입니다. 실제 접근 제어는 인증 모듈과 다양한 보기 도우미를 사용하여 이루어집니다.

CanCanCan 설치

설치는 아래 명령을 실행하는 것만큼 쉽습니다:

 

Pundit과 마찬가지로 CanCanCan을 사용하면 "능력" 클래스라는 일반 Ruby 클래스 개체 내에서 모든 액세스 규칙을 정의할 수 있습니다. 다음 생성기 명령을 사용하여 해당 작업을 수행해 보겠습니다.

 

아래 클래스 객체가 생성됩니다:

 

다음에는 능력 클래스가 예시 Rails 앱에 대한 액세스 규칙을 정의하는 방법에 대해 자세히 알아 보겠습니다.

CanCanCan 능력 정의 및 확인

Pundit 예에서와 동일한 사용자 역할인 작가 및 편집자를 사용합니다. 작성자는 자신의 게시물을 생성, 편집, 업데이트, 삭제할 수 있으며 다른 작성자의 게시물을 볼 수 있습니다. 편집자는 자신만의 게시물을 작성하는 것 외에는 모든 작업을 수행할 수 있습니다.

CanCanCan을 사용하려면 먼저 다음 형식에 따라 각 사용자 또는 역할이 능력 클래스에서 액세스할 수 있는 항목을 정의하세요.

 

예를 들면:

 

그런 다음 컨트롤러에서 edit 예시를 사용하여 특정 작업에 대한 액세스 규칙이 존재하는지 확인합니다. 행동:

 

이를 적용한 상태에서 다른 작성자로 게시물 편집 보기를 방문하면 아래 오류가 발생합니다:

Ruby 인증 마스터하기:Pundit과 CanCanCan

Pundit에서 했던 것처럼 이 오류를 해결하고 사용자에게 더 나은 오류 페이지를 보여드리겠습니다.

CanCanCan의 "액세스 거부" 오류 처리

리소스가 승인되지 않을 때마다 CanCanCan은 CanCan::AccessDenied을 발생시킵니다. 오류. 이 예외를 포착하는 가장 쉬운 방법은 ApplicationController을 수정하는 것입니다. 다음과 같습니다:

 

이렇게 하면 좋은 사용자 경험을 얻을 수 있습니다. 아래 스크린샷에서는 승인되지 않은 사용자가 홈 페이지로 리디렉션되고 관련 플래시 메시지가 표시됩니다.

Ruby 인증 마스터하기:Pundit과 CanCanCan

사용자에게 표시되는 오류 메시지를 맞춤설정할 수도 있습니다.

 

앱이 XML을 응답으로 제공하거나 CanCanCan::AccessDenied 처리에 대해 더 자세히 알아보고 싶은 경우 예외는 CanCanCan의 문서를 확인하세요. 지금은 CanCanCan의 다양한 기능을 결합하여 보다 강력한 인증 레이어를 만드는 방법을 살펴보겠습니다.

여러 CanCanCan 기능 결합

능력 클래스의 자원에 대해 여러 액세스 규칙을 정의할 수 있습니다. 예를 들어 작가와 편집자 역할을 맡으면 다음과 같이 할 수 있습니다:

 

문제는 왜 이 일을 하시겠습니까?

CanCanCan을 사용하면 하나의 능력 파일에 모든 액세스 규칙을 정의할 수 있습니다. 여기에는 장점과 단점이 모두 있습니다.

모든 규칙이 한 곳에 정의되어 있으므로 모든 규칙을 한 곳에 두는 것은 액세스 규칙을 처리하는 데 매우 편리합니다.

그러나 앱이 많은 사용자 역할을 다루거나 인증이 필요한 여러 리소스가 있는 경우 능력 클래스가 처리하기에는 너무 크고 복잡해질 수 있습니다. 이를 처리하는 한 가지 방법은 다음과 같이 메소드 정의를 사용하도록 능력 클래스를 재구성하는 것입니다:

 

CanCanCan에는 이 문서에서 효과적으로 다룰 수 있는 것보다 더 많은 내용이 있습니다. 자세한 내용은 자세한 CanCanCan 문서를 확인하세요.

마무리하기 위해 각 라이브러리의 기능을 간략하게 살펴보고 다른 라이브러리보다 하나를 선택해야 하는 이유를 설명하겠습니다.

기능 비교:Ruby 앱의 Pundit과 CanCanCan

  • 파일 구성 - Pundit을 사용하면 여러 정책 파일에 걸쳐 앱 승인을 쉽게 구성할 수 있습니다. 그러나 CanCanCan을 사용하면 인증 규칙이 하나의 기능 파일에 존재합니다. 여러 능력 파일로 작업하는 것은 여전히 가능하지만 이는 기본 구현 스타일이 아닙니다.
  • 테스트 - Pundit의 여러 능력 클래스에 비해 권한 코드는 대부분 단일 클래스 내에 상주하므로 CanCanCan에 대한 테스트 작성은 Pundit보다 쉬울 수 있습니다.
  • 도우미 - 두 라이브러리 모두 뷰 레이어의 권한을 확인하기 위한 다양한 뷰 도우미를 제공합니다. CanCanCan은 can?를 제공합니다. Pundit은 policy와 비교적 유사한 기능을 제공하지만 도우미.
  • 통합 고안 - 기사에서 사용한 예에서 볼 수 있듯이 두 라이브러리 모두 Devise와 매우 잘 통합됩니다.

마무리

이 기사에서는 Ruby and Rails 생태계에서 가장 인기 있는 두 가지 인증 gem인 Pundit과 CanCanCan을 살펴보았습니다.

두 라이브러리 모두 Rails 앱에서 권한을 관리하기 위한 다양한 기능 세트를 제공합니다. 이로 인해 어떤 보석을 선택해야 할지 결정하기가 거의 불가능합니다. 두 보석 모두 가장 복잡한 권한 설정도 관리할 수 있습니다.

앱에서 Pundit과 CanCanCan을 사용해 보고 어느 것이 귀하의 요구 사항에 가장 적합한지 확인해 보시기 바랍니다.

즐거운 코딩 되세요!

추신 Ruby Magic 게시물이 보도되는 즉시 읽으려면 Ruby Magic 뉴스레터를 구독하고 단 하나의 게시물도 놓치지 마세요!