인증과 인가를 어느 계층 해야하는지에 대해 이야기 하기 전, 간단하게 인증과 인가를 정의하고 넘어가자. 인증이란 유저가 누구인지 검증하는 것이다. 예를 들어 웹사이트에 로그인을 한다면 서버는 해당 유저가 누구인지 특정할 수 있게 된다. 인가란 유저가 접근할 수 있는 리소스가 무엇인지 판단하는 것이다. 예를 들어 어드민 유저의 경우에만 백오피스에 접근할 수 있도록 하는 등 권한에 대한 것이 일반적이다.
그렇다면 인증과 인가 로직은 어디서 수행해야 할까? 일반적으로 컨트롤러와 서비스 계층 사이에서 고민이될 것이다. 이때 컨트롤러란 URL 또는 스케쥴링 등을 통해 호출 되는 계층으로 기능을 수행하기 위한 서비스를 호출하고, 필요한 요청/응답 형태로 매핑하는 계층이다. 서비스란 기능을 수행하기 위한 실제 비즈니스 로직을 가지고 있는 곳이다. 일반적으로 어플리케이션의 진입점을 서비스 계층부터로 보기 때문에 컨트롤러는 비즈니스 로직을 담지 않고 얇게 유지하려고 노력한다. 인증과 인가는 비즈니스 로직이니 서비스에서 해야할까? 아니면 웹 기술에 의존적인 로직이니 컨트롤러에서 해야할까?
결국 이 모두는 기능과 리소스에 대한 접근 제어를 하기 위한 것이다. 따라서 접근 제어 자체를 수직적/수평적 2가지로 분리하여 생각해보는 것이 도움이 될 수 있다. 수직적 접근 제어란 일부 유저는 접근할 수 있지만, 다른 유저들은 접근할 수 없는 기능이다. 예를 들어 누구나 웹사이트의 홈페이지를 볼 수 있지만, 어드민 유저만 일반 유저를 밴할 수 있다. 수평적 접근 제어란 여러 유저가 접근할 수 있지만, 데이터가 분리되어 있는 것이다. 예를 들어 모든 유저가 나의 주문 목록에 접근할 수 있지만, 본인의 데이터만 조회할 수 있다.
인증은 유저를 식별하는 것으로 그 자체에 어떤 비즈니스적 로직이 있지는 않다. 그리고 통신 방식에 영향을 받기 쉽다. 따라서 컨트롤러 계층에서 처리함이 바람직 할 것이다. 인가는 제어하려는 방식이 수직적인지 수평적인지에 따라 다르다. 만약 수직적이라면 단순 접근에 대한 제한이고, 유저별로 다르게 수행되는 기능이 아니므로 컨트롤러에서 인가하는 것이 일반적이다. 수평적 접근 제어의 경우 비즈니스 로직의 일부로 보고 서비스에서 수행할 수 있을 것이다.