header-cover

로그인 구현 방식(JWT , Session , OAuth 2.0)

현재 자주 사용되고 있는 로그인 구현 방식과 OAuth를 구현하는 방식을 작성하였습니다

2022-11-09·

도입

 
웹사이트에서는 요청에 따라 사용자가 로그인을 하였는지에 관한 인증상태를 관리해야 할 필요가 있다. 사용자가 어떠한 동작이나 어떠한 요청을 보낼 때 마다 계속 로그인을 통해 사용자 인증을 요구한다면 그 웹사이트는 그 사이트에 사용자 경험은 떨어지고 결국 아무도 사용하지 않게 될 것이다. 이처럼 사용자가 로그인 하게 되었을 때 사용자의 로그인 상태를 서버에서 처리할 수 있도록 하는 인증 방식이 있는데 세션(Session)과 JWT , Oauth 방식이 있습니다.
(참고 : 쿠키 방식도 있다)
 

세션

 
세션이란 쉽게 말하면 서버의 컴퓨터(서버에 세션 저장소)에 클라이언트의 정보를 기억하고 유지하는 것 입니다.
사용자(정확히는 브라우저)가 로그인을 하였다면 서버의 컴퓨터(세션 저장소)에서 사용자 정보(주로 브라우저에 쿠키에 저장하게 됩니다)를 확인한 뒤 확인 되었다면 일정시간 동안 유지시키며 이후 사용자가 서비스를 요청할 때 마다 세션 저장소에서 세션을 조회하고 작업을 처리하는 방식입니다. 
세션은 서비스가 돌아가는 서버 측에 데이터를 저장하고, 세션의 키(혹은 ID라고도 함)값만을 클라이언트 쿠키에 남겨둡니다. 브라우저는 필요할 때마다 쿠키에 있는 세션 키값을 이용하여 서버에 저장된 데이터를 사용하게 됩니다.
 
이러한 방식의 장점은 개발자 입장에서 구현이 매우 쉽고 서버에 세션 ID값만 가지고 접근할 수 있고 서버에 저장하기 때문에 접근이 매우 용이하고 관리가 효율적입니다
단점은 서버에서 클라이언트의 상태를 모두 유지하게 된다면 서버 컴퓨터의 과부하가 걸릴 수 있고 또한 서버의 세션을 유지시킬 때 서버의 인스턴스가 여러 개가 된다면, 모든 서버끼리 같은 세션을 공유하여야 하므로 확장하는데 어렵고 세션 정보 전용 데이터베이스를 만들어야하는 번거로움이 있습니다. CORS이유도 있다
 
notion image
 
 

JWT

 

개요

JWT는 사용자 정보를 JSON 객체에 담아 이를 암호화하고 해싱 작업을 거쳐 문자열 토큰을 생성
 
JWT는 JSON Web Token의 약자이며 JSON 방식의 데이터 포맷을 이용하여 사용자 정보를 저장하는 웹토큰이며, 이때 이러한 토큰 자체의 정보를 사용하며 정보를 전달하게 됩니다.
사용자가 로그인을 시도하게 된다면 서버는 사용자의 정보를 찾아보고 있다면 키값을 통해 여러가지 정보를 암호화하여 jwt를 생성한 뒤 전달해주게 됩니다. 사용자는 이렇게 발급받은 jwt를 서버에 요청을 전달할 때마다 함께 전달하고 서버는 암호화했던 키 값을 통해 토큰의 유효성 인증을 거친 뒤(auth) 사용자에게 정보를 제공해주게 됩니다.
 
notion image
 
이러한 방식의 장점세션방식에 비해 서버에서 사용자 로그인 정보를 저장하는데 사용되는 리소스가 적다는 점( 사용자 인증에 필요한 정보를 토큰 자체에 담고 있다면 저장소 또한 필요없음)과 토큰을 해제할 수 있는 키값만 있으면 되기 때문에 서버확장이 용이하다는 점을 통해 세션과 대비되는 장점을 가지고 있습니다 ( 이러한 키값을 사용자 정보 DB에 추가하는 방식)
단점은 개발자 입장에서 세션보다 구현이 다소어렵고 누군가가 토큰을 탈취한다면, 그 토큰을 이용하여 권한을 수행 가능하기 때문에 보안에 신경쓸 필요가 있습니다
 

구조 (참고)

notion image
  • 헤더 : 토큰 타입(JWT ) , 해시 알고리즘 ( 데이터 자체가 함수를 통해 키로 변경시키는 자료구조)
    • JWT를 검증하는데 필요한 정보를 가짐
    •  
       
  • 내용 : 토큰 정보와 사용자 정보 등등 → 클레임 셋이라고도 함
JWT에 대한 내용(토큰 생성자(클라이언트)의 정보, 생성 일시 등)이나 클라이언트와 서버 간 주고 받기로 한 값들로 구성
notion image
 
  • 서명 : 보안성을 높이기 위해 사용
    • 헤더와 내용을 합쳐서 문자열을 만들고 이것을 검증함
 
 
var token = jwt.sign({ foo: 'bar' }, 'shhhhh'); var token = jwt.sign({ foo: 'bar' }, privateKey, { algorithm: 'RS256'});
 

Oauth

 

개요

 
notion image
 
OpenID Authentication의 줄임말로서, 말 그대로 인터넷 사용자들이 비밀번호를 제공하지 않고 다른 웹사이트 상의 자신들의 정보로 웹 사이트나 애플리케이션의 접근 권한을 부여할 수 있는 공통적인 수단으로 사용되는, 접근 위임을 위한 개방형 표준
이러한 인증 방식은 사용자들에게 외부 계정(Resource Server → Naver , Facebook , Google)을 기반으로 간편히 회원가입 클릭 한 번으로 간편하게 로그인할 수 있을 뿐만 아니라, 연동되는 외부 웹 어플리케이션에서 제공하는 기능을 간편하게 사용할 수 있다는 장점이 있습니다. 예를 들어, 외부 웹 어플리케이션에 Google로 로그인하면 API를 통해 연동된 계정의 Google Calendar 정보를 가져와 사용자에게 보여줄 수 있습니다.
 
사용자들이 자신들의 정보를 우리의 서비스에 알려주지 않아도 Oauth라는 간단한 인증 방식을 통해 안전하게 정보를 넘겨주는 것이라고 할 수 있습니다.
 
하지만 단점으로 개발자 입장에서 구현이 가장 복잡한 로그인 구현방식이며 사용자 인증 과정에서 웹서비스에 맞는 최소한의 사용자 정보를 얻기 위해 추가 요청을 해야 하는 경우가 있습니다.
 
최근엔 Oauth 2.0을 사용하는데 기존에 1.0에 있어서 보안적인 문제가 있어 보안적인 문제를 개선하고 다양한 확장성 기능을 추가한 버전입니다(참고)
 

도입

우리가 Oauth 기능을 우리의 서비스에 구현하기 위해서 우선 Resource 서버에 자신의 웹 URL 등등 정보를 등록해야합니다. (여러 보안적인 위험을 방지하기 위함 → XSS , 피싱 사이트)
 
이렇게 등록을 하기 되면 세가지 정보를 부여 받게 됩니다.
  1. Client ID : 웹어플리케이션을 구분하는 식별자
  1. Client Secret : Client ID에 대한 비밀키
  1. Authorized redirect URL : Authorization Code를 전달받을 리다이렉트 주소입니다.
 

과정

 
GitHub의 Oauth를 이용하였는데 깃허브에서는 Oauth를 위해 사용자를 이동시키면서 아래 주소로 Client IDAuthorized redirect URL을 보내도록 요구합니다.
 
GET https://github.com/login/oauth/authorize?client_id={client_id}&redirect_uri={redirect_uri}?scope={scope}
 
이때 깃허브에서는 Client ID 를 검사하여 등록된 정보가 있는지 확인하고 Authorized redirect URL 이 등록된 URL과 일치하는지 확인합니다( 일치하지 않으면 보안상의 문제로 거부함 )
 
notion image
 
이제 사용자는 해당 페이지로 이동 한 뒤 소셜 로그인을 진행하고 명시된 범위의 정보들을 정말로 보내줄 것인지 확인하고 최종적으로 사용자가 허용한다면 Resource 서버(깃허브)로 우리의 웹 어플리케이션이 접근할 수 있게 됩니다.
 
허용할 것인지를 물어봄
허용할 것인지를 물어봄
 
 
우리 웹 어플리케이션은 위 과정을 전부 거치고나면 우리가 작성해두었던 Redirect URL로 Resource 서버 (깃허브)가 Access Token을 발급하기 전에, 임시 암호인 Authorization Code를 함께 발급합니다.
 
notion image
 
이 코드 서버에 저장해두고 웹에서 ID와 비밀키 및 코드를 사용자를 거치지 않고 Resource 서버에 직접 전달합니다. Resource 서버는 정보를 검사한 다음, 유효한 요청이라면 Access Token을 발급하게 됩니다.
 
이렇게 발급받은 Access Token을 서버에 저장해두고 Resource 서버의 기능을 사용하기 위한 API 호출시 해당 토큰을 헤더에 담아 보내면 됩니다.
 
이후 Access Token을 헤더에 담아 Github API를 호출하면, 해당 계정과 연동된 Resource 서버가 제공하는 데이터 및 기능들을 내가 만든 웹 어플리케이션에서 사용할 수 있습니다.
 
notion image
 
 
더 이론적으로 자세한 내용과 한번 읽어보면 좋을 법한 것들