Vue.js를 활용해 프로젝트를 만들고 있다.
백단과 화면단을 완전히 분리시키기 위해 REST API를 만들고, axios를 통해 서버와 통신한다는 것까진 감이 잡혔다.
하지만 또다른 고민이 생겼다.
만약 로그인을 한 사용자만 접근할 수 있는 마이페이지에 비로그인 사용자가 접근한다면 어떻게 해야할까?
또 관리자 권한을 가진 사용자만 접근할 수 있는 관리자 페이지에 일반 회원이 접근한다면?
JSP로 화면을 구현했던 지난 프로젝트들에서는 시큐리티에서 URI의 권한 여부를 설정하고, 권한이 없는 사용자가 접근하면 에러페이지를 반환하도록 했다.
하지만 페이지 이동이 프론트단의 라우터를 통해 이루어지는 CSR 프로젝트에서는 불가능한 일이다.
RESTful
REST API는 기본적으로 상태 없음을 지향한다.
세션을 사용하는 것은 RESTful하지 않다고 여겨지기 때문에, 그동안 사용했던 스프링 시큐리티 세션 기반 인증은 적절하지 않다.
검색해보니 세션 기반 인증을 사용하는 방법도 있기는 했다.
- 로그인시 사용자 정보를 Vuex 상태에 저장한다.
- 페이지 라우팅시 beforeEach()에서 상태 정보를 확인해 페이지 이동 여부를 결정한다.
하지만 과연 이 방법이 맞는지 의문이 들었다.
Vuex 상태 그거 그냥 개발자도구에서 devtools로 바꿔버리면 되는거 아닌가?
권한이 없어도 있는 척, 로그인 안해도 한 척 가능할 것 같았다.
그럼 컨트롤러 메서드에서 Authentication 객체를 인자로 받고 객체의 null 여부를 따져서 인증/인가 여부를 확인하면 되긴 하겠다...
하지만 애초에 로그인 정보를 저장하고 유지한다는 것 자체가 RESTful하지 않다는 것이 영 거슬린다🤔
이런저런 이유로 다 제외하고 나니.. 애써 외면해보았던 마지막 방법밖에 없었다..
JWT
JSon Web Token
JWT는 인터넷 표준 인증방식의 일종이다.
인증에 필요한 정보들을 담고 있는 Json 객체를 암호화한 문자열이다.
요청을 보낼 때 토큰을 헤더에 포함해서 보내면 서버는 이를 복호화하고 관련 정보를 확인해 인증을 수행한다.
이 과정에서 정말 서버가 발급한 토큰이 맞는지 대조하는 과정을 거치기 때문에, 앞서 언급한 변조 문제는 걱정하지 않아도 된다.
무상태성
JWT는 서버에 사용자 정보를 저장하는 세션과 달리, 상태를 저장하지 않는다.
클라이언트에게 암호화된 토큰을 발급하고, 요청시 함께 보낸 토큰을 복호화해 풀어내는 방식으로 무상태성을 유지하는 것이다.
이러한 상태 없음 속성 때문에, 서버와 클라이언트가 완벽하게 분리되어 있는 REST API에서 주로 사용하는 것이다.
동작 원리
- 클라이언트가 아이디, 패스워드를 통해 로그인을 요청한다.
- 서버(DB)에 해당 정보와 일치하는 유저가 있다면 Access Token, Refresh Token 발급한다.
- 앞으로 클라이언트는 발급받은 Access Token을 헤더에 담아 요청을 보낸다.
🤯
결제 API를 사용하면서 토큰을 발급받은 것 외에는 토큰을 사용해본적이 없어서 애써 외면했던 건데 방법이 없다...
앞으로 열심히 공부해야겠다🧐