본문 바로가기

BackEnd/Spring, SpringBoot

[SpringBoot]Oauth2.0 jwt token

Oauth2.0

  많은 사이트들, 어플리케이션에서 카카오 아이디 로그인, 구글계정 로그인, 페이스북 로그인, 네이버 로그인 등을 통해 인증, 로그인하는 경험이 많았을 텐데 이때 사용되는 프로토콜이 Oauth이다

Client : 우리가 만든 서비스(Third-Party Application)
Resource Owner : 사용자로서 우리가 만든 서비스를 사용할 유저, Resource Server에 인증할 정보를 가지고 있다Resource Server : Resource Owner의 리소스를 가지고 있으며 보호된 리소스 요청에 응답
Authoriazion Server : Client 서비스가 Resource Owner의 리소스를 사용할 수 있도록 인가 해주는 역할
(Resource Server + Authoriazion Server : 위에서 말한 구글, 페이스북, 카카오, 네이버와같은 Oauth 제공자 기능을 명확히 하기 위해 두 서버로 나누기도 하지만 간단한 경우 합쳐 구현하기도 한다)

 일반 로그인이 아이디, 비밀번호를 직접 DB에 암호화하여 저장하거나 사용자의 Device에 저장하거나 하는 방식으로 
직접 저장해두고 인증한다면 Oauth는 Resource Server에서 제공하는 방식을 통해 인증을 진행한다

 Oauth를 사용하면 우리가 개발하는 서비스와같이(?) 보안의 수준을 확신할수 없는 애플리케이션에서의 인증 시 보안상 이점을 가질 수 있고 해당 Resource Server에서 제공하는 api들을 만들 서비스에 응용할 수 있다는 장점이 있다
타사의 인증된 회원정보를 이용한 로그인에 가장 많이 사용되며, 예를 들어 Facebook을 통해 Oauth 인증을 구현시 친구목록 불러오기, 피드작성 처럼 Resource Server에서 제공하는 기능들을 우리 서비스에서 api형식으로 사용할수 있다

동작과정

 - Resource Server와 Authorizion Server를 Resource Server로 통칭하여 설명
 서비스는 미리 Resource Server에 등록되어있어야 한다
 1.  우리가 만든 서비스에서 인증이 필요한 경우 사용자에게 Resource Server에 인증받도록(ex. 구글로그인) 한다
 2.  사용자(Resource Owner)는 로그인, 사용권한 동의 등의 과정을 통해 Resource Server에 인증을 요청한다
 3.  사용자의 동의 시 Resource Server에서 우리가 만든 서비스로 인증코드를 준다
 4.  서비스는 Client ID, Client Secret, 인증코드를 Resource Server로 전송하여 Access Token을 받는다
 5.  이후 Resource Owner의 요청에 따라 Access Token을 이용하여 Resource Server에서 제공하는 기능을 사용한다 

JWT(Json Web Token)

JWT는 두 지점사이에 정보를 전달하는데 사용되며 json 형식을 가진 간편하고 신뢰성있는 웹표준이다

토큰의 변조를 방지하기위해 HMAC(Hash-based Message Authentication) 방법을 사용하거나 public/private key pair의 RSA or ECDSA를 사용할 수 있다

구조

 [ Header.Payload.Verify Signature ] 의 구조를 가진다

Header
 - 토큰유형
 - 서명알고리즘

Payload
 정보는 Payload에 담는다
 * Claim : 개체(사용자 등), 추가적인 데이터

 
 Registered Claims : 이미 정의된 클레임(권장)
  - Iss(Issuer) : 토큰 발행자
  - exp(expiration time) : 만료시간
  - sub(subject) : 토큰 제목
  - aud(audience) : 토큰 대상자
  ...

 Public Claims : 공개된 클레임
  - Registered Claims에 정의되지 않은 Claim들 , Registered Claims와 충돌을 방지하기위해 URL 형식으로 정의

 Private Claims :  비공개 클레임
 - 정보를 공유하는 개체간(서버 - 클라이언트) 동의하에 생성하는 클레임

Verify Signature 
 Base64 방식으로 인코딩된 header와 payload를 합쳐 header의 서명 알고리즘을 사용해 암호화하여 생성


Header와 Payload는 탈취시 Decoding을 통해 정보확인이 가능하니 중요한 정보를 담지않도록 하여야 한다
하지만 Verify Signature에 Header, Payload, secret을 통해 암호화된 정보가 있으므로 인증시 보안성이 있다

- JWT 확인시 https://jwt.io/ 사이트를 활용