[OAuth + Spring Boot + JWT] 1. OAuth란? 프론트엔드와 백엔드의 역할

Junseo Kim·2021년 7월 11일
47
post-thumbnail

📚 OAuth(Open Authorization)란?

OAuth는 인증을 위한 프로토콜이다. 다른 인터넷 서비스의 기능을 다른 어플리케이션에서도 사용할 수 있게 해준다.

OAuth는 인증(Authentication)과 인가(Authorization)를 모두 포함하고 있다. 그중 OAuth는 인가에 좀 더 초점을 맞추고 있다.

네이버나 카카오 로그인을 생각해보자. 네이버나 카카오 사용자인지 인증하는 과정은 네이버나 카카오가 담당한다. OAuth는 이렇게 인증도 제공하지만, 주요 목적은 인증된 사용자에게 사용자의 이름이나, 이메일을 가져온다든지 하는 권한을 제공해주는 것이다.

OAuth 2.0 부터는 반드시 HTTPS 사용, 웹이 아닌 애플리케이션도 지원, Access token 만료 시간 설정 등이 추가되었다.

📝 용어 정리

OAuth2.0 기준

  • Resource Owner: 말 그대로 사용자라고 생각하면 된다. 사람이 될 수도 있고, Application 자체가 될 수도 있다.(ex. 나)
  • Client Application: 사용자가 사용하는 서비스 애플리케이션. 서버, 데스크톱 등 어떤 기기든 될 수 있다.(ex. velog)
  • Resource Server: OAuth를 통해 인증, 인가를 제공해주는 서버. 자원 서버. 자원(이름, 이메일, 프로필 사진 등)을 제공해준다.(ex. github, naver, kakao, google)
  • Authorization Server: OAuth를 통해 인증, 인가를 제공해주는 서버. 인증 서버. 토큰을 발급해준다.(ex. github, naver, kakao, google)

Resource Server와 Authorization Server는 자원과 인증으로 분리되어 있긴 하지만, 둘 다 같은 소속이라고 보면 된다.(ex. github, naver, kakao, google 등)

velog를 예시로 들어 간단한 흐름을 한 번 그려보았다.

📝 OAuth 2.0 인증 방식

OAuth 2.0에는 4가지 인증 방식이 있다.
1) Authorization Code Grant
2) Implicit Grant
3) Resource Owner Password Credentials Grant
4) Client Credentials Grant

웹이나 앱에서는 Authorization Code Grant 방식이 가장 많이 사용된다. 따라서 Authorization Code Grant 방식을 기준으로 설명할 것이다.

Authorization Code Grant

OAuth 서버에서 client Application에게 바로 access token을 넘겨주는 것이 아니라, Authorization code를 넘겨주고, client Application은 Authorization code를 통해 access token을 발급 받아, access token으로 허가된 리소스 요청을 하는 방식이다.

이렇게 Authorization code를 도입하게 되면 access token 자체는 백엔드에서만 존재하게 되므로, 중간에 access token을 탈취당하지 않게 된다.

📝 OAuth + JWT 예시

위의 그림과 같이 OAuth를 통해 SNS 로그인 기능을 구현했어도 실제 개발할 애플리케이션의 인증 방법은 별도로 필요하다. 즉, 세션/쿠키나 토큰을 사용하여 별도로 인증 작업을 해줘야한다.

아래와 같은 상황이라고 가정하자.

새로운 웹 애플리케이션을 프론트, 백 나눠서 개발하려고한다. github 기능을 사용해야하는 애플리케이션이기 때문에, 자체 로그인을 구현하기보다 github을 통해 로그인을 하려고한다. 이때 github 사용자의 이름, 이메일, 프로필 사진 정보를 가져와서 회원으로 등록하려고 한다. 회원은 애플리케이션의 특정 게시물을 조회할 수 있다.

우리는 github을 통해 로그인(인증), github 사용자의 이름, 이메일, 프로필 사진 정보를 가져와서(인가) 이 2가지를 OAuth를 이용해서 구현하고, 회원은 애플리케이션의 특정 게시물을 조회할 수 있다를 처리할 때는 JWT를 사용하려고 한다.

인증 방식으로 토큰 선택 이유

세션 대신 토큰을 사용하려는 이유는 확장성 때문이다. 만약 여러 서버가 돌아가는 상황이라면, 각 서버마다 세션 저장소를 두거나, 공통 세션 저장소를 만들어야하는데, 이 또한 비용이다. 반면에 토큰은 stateless 하기 때문에 확장에 용이하다.

다만, 토큰은 한 번 발급되면 강제로 만료시킬 수 없다는 단점이 있다. 따라서 만료 시간이 짧은 access token과 만료 시간이 긴 refresh token을 나눠서 사용하는 것이다.

토큰은 실제로 로그인을 유지하고 있는 것이 아니라 로그인이 유지된 것 처럼 행동한다.(클라이언트가 access token을 저장해두고, 요청 때 마다 보내는 방식) 따라서 만약 access token이 만료된 것이 아니라면, 로그아웃을 했더라도 해당 access token만 가지고 있다면, 로그인 된 상태처럼 행동할 수 있다고 한다.

프론트엔드 역할

  • github OAuth 서버로 github 로그인 요청 후, Authorization code 발급 받아, 백엔드에 전달
  • 백엔드에서 응답 받은 access token, refresh token 저장해두기
  • 권한이 필요한 요청마다 Authorization 헤더에 access token 같이 보내주기
  • access token이 만료되었다면, refresh token 보내서 갱신하기(프론트에서 요청 날릴 때 access token이 만료됨을 미리 판별하여 갱신 요청을 보낼 수 있음)
  • refresh token 만료 기간이 7일 이내면, refresh token 재발급 요청

백엔드 역할

  • Authorization code로 github OAuth 서버에 토큰 요청
  • (로그인 할 때 이외에 OAuth 서버와 통신이 필요한 경우 발급 받은 토큰 저장해야 할듯)
  • Access token으로 이름, 이메일, 프로필 URL 정보 요청
  • db에 존재하지 않는 유저라면, 새로 등록. db에 존재하는 유저라면 정보 업데이트
  • 유저의 primary key 값으로 JWT 토큰(access token & refresh token) 생성. 일반적으로 access token은 한 시간, refresh token은 2주로 생성(본인 애플리케이션에 맞게 변경하여 사용)
  • refresh token은 DB나 Redis에 저장
  • 유저 정보, access token, refresh token 프론트로 전달
  • access token 만료시 refresh token 검증 후, 재발급

최종 설계

🚗 Next

다음 포스팅은 spring security를 사용하여 github 로그인을 구현해보고, spring security의 구조를 살펴본 후, spring security 없이 github 로그인을 구현해보도록 한다. 그 후, JWT 토큰 기능도 추가할 계획이다.

reference

1개의 댓글

comment-user-thumbnail
2023년 4월 12일

도움이 많이 되었어요. 감사합니다.

답글 달기