인가
권한 확인은 어디에서 해아됩니까?
권한을 확인할 위치를 결정할 때에는 다양한 계층에서 여러 번의 확인을 실시하여 깊이 있는 방어를 적용합니다. 낮은 수준의 계층부터 시작하여, finders 및 services와 같은 낮은 수준의 계층부터 시작하여 GraphQL, 공개 REST API, 그리고 컨트롤러와 같은 고수준의 계층으로 이동합니다.
자세한 정보는 추상화 재사용 가이드라인을 참조하세요.
같은 리소스를 여러 지점에서 보호하는 것은 하나의 방어 계층이 손상되거나 빠졌을 때에도 고객 데이터가 추가적인 계층에 의해 보호된다는 것을 의미합니다.
권한에 대한 자세한 정보는 보안 코딩 가이드라인의 권한 섹션을 참조하세요.
고려 사항
서비스나 finders는 적절한 위치입니다. 왜냐하면:
- 여러 엔드포인트가 services나 finders를 공유하기 때문에 하향식 로직이 재사용될 가능성이 더 높습니다.
- 때로는 권한 부여 논리를 레코드를 필터링하기 위한 DB 쿼리에 통합해야 할 수도 있습니다.
- 표시 계층에서 권한 확인을 제공하는 것은 UX를 개선하기 위해서만 해야 하며, 보안 확인이 아닙니다. 예를 들어, 버튼과 같은 비데이터 요소를 표시하고 숨기는 데에 사용됩니다.
깊이 있는 방어의 단점은 다음과 같습니다:
-
DeclarativePolicy
규칙은 비교적 성능이 우수하지만 조건은 데이터베이스 호출을 수행할 수 있습니다. - 높은 유지보수 비용입니다.
예외
특정 경우에 대한 위험과 단점을 고려한 후에 개발자는 권한을 한 곳에서만 확인할 수 있습니다.
예외를 만들 때에는 예외를 만들 때 도메인 논리(services나 finders)를 진실의 원천으로 선호합니다.
백엔드 워커 논리와 같은 논리는 현재 사용자를 기반으로 하는 권한이 필요하지 않을 수 있습니다. 서비스나 finider의 생성자가 current_user
를 예상하지 않는 경우 권한을 확인하지 않을 가능성이 높습니다.
프론트엔드
UI 요소에서 능력 확인을 사용할 때, 백엔드 코드의 기반이 되는 능력 확인 또한 반드시 사용하세요. 이렇게 하면 사용자가 적절한 액세스 권한을 가지지 않은 경우에는 기능을 사용할 수 있는 방법이 절대로 없도록 보장할 수 있습니다.
UI 요소가 HAML인 경우 embedded Ruby를 사용하여 Ability.allowed?(user, action, subject)
를 확인할 수 있습니다.
UI 요소가 JavaScript나 Vue인 경우, ApplicationController
를 상속하는 모든 컨트롤러에서 사용할 수 있는 push_frontend_ability
메서드를 사용하세요. 이 메서드를 사용하여 능력을 노출할 수 있습니다. 예를 들어:
before_action do
push_frontend_ability(ability: :read_project, resource: @project, user: current_user)
end
그런 다음 JavaScript에서 능력 상태를 다음과 같이 확인할 수 있습니다.
if ( gon.abilities.readProject ) {
// ...
}
JavaScript에서의 능력 이름은 항상 낙타 표기법이므로 gon.abilities.read_project
를 확인하는 것은 작동하지 않습니다.
Vue 템플릿에서 능력을 확인하려면 Vue에서 능력에 대한 개발자 문서를 참조하세요.
팁
클래스가 current_user
를 허용하는 경우, 해당 클래스가 권한 확인을 담당할 수 있습니다.
예시: 새로운 API 엔드포인트 추가
기본적으로 엔드포인트에서 권한 확인을 실시합니다. 기존 능력 확인이 맥락에 맞는 경우에는 확인하는 것이 합리적일 수 있으며, 그렇지 않은 경우 새로운 능력을 추가해야 할 수 있습니다.
그리고 대부분의 엔드포인트는 리소스에 대한 CRUD (생성, 읽기, 업데이트, 삭제) 동작으로 깔끔하게 분류될 수 있습니다. services와 능력도 같은 방식을 따르기 때문에 많은 경우 ‘Projects::CreateService’나 ‘:read_project’와 같은 이름을 갖습니다.
예를 들어, 우리가 전체 엔드포인트를 서비스로 분리한다면, can?
확인은 이제 해당 서비스에 있을 것입니다. 만약 서비스가 목적에 맞게 수정 중인 기존의 finder를 재사용한다면 finder가 능력을 확인하도록 만들어야 할까요?
- 만약 finder가
current_user
를 허용하지 않고 따라서 권한을 확인하지 않는 것이면 아마도 아니오. - 만약 finder가
current_user
를 허용하고 권한을 확인하지 않는 것이면 finder의 다른 사용 사례를 반드시 다시 확인하고 권한 부여를 추가해야 할 수 있습니다. - 만약 finder가
current_user
를 허용하고 이미 권한을 확인한다면 여기서 우리의 경우를 추가해야 하거나 기존의 확인 사항이 적절한지를 고려해야 합니다.