1. JWT(Json Web Token) 이란?

 

  1 - 1) JSON Web Token (JWT) 은 두 개체에서 JSON 객체를 사용하여 가볍고 자가 수용적인 방식으로 정보를 안전성 있게 전달한다.

 

  1 - 2) 수많은 프로그래밍 언어에서 지원된다.

  JWT 는 C, Java, Python, C++, R, C#, PHP, JavaScript, Ruby, Go, Swift 등 대부분의 주류 프로그래밍 언어에서 지원된다.

 

  1 - 3) 자가 수용적 (self-contained)이다.

  JWT는 필요한 모든 정보를 자체적으로 지니고 있다.

  JWT 시스템에서 발급된 토큰은, 토큰에 대한 기본정보, 전달할 정보 그리고 토큰이 검증됐다는 것을 증명해주는 signature를 포함하고 있다.

 

  1 - 4 ) 쉽게 전달될 수 있습니다

  JWT는 자가 수용적이므로, 두 개체 사이에서 손쉽게 전달될 수 있다.

  웹서버의 경우 HTTP의 헤더에 넣어서 전달할 수도 있고, URL 의 파라미터로 전달 할 수도 있다.

 

 

 

2. JWT는 어떤 상황에서 유용한가?

 

  2 - 1) 회원 인증

  JWT를 사용하는 가장 흔한 시나리오이다.

  유저가 로그인을 하면, 서버는 유저의 정보에 기반한 토큰을 발급하여 유저에게 전달한다.

  그 후, 유저가 서버에 요청을 할 때마다 JWT를 포함하여 전달한다.

  서버가 클라이언트에게서 요청을 받을 때마다, 해당 토큰이 유효하고 인증됐는지 검증을 하고, 유저가 요청한 작업에 권한이 있는지 확인하 여 작업을 처리한다.
  또한 서버 측에서는 유저의 세션을 유지할 필요가 없다.

  즉 유저가 로그인되어있는지 안되어있는지 신경 쓸 필요가 없고, 유저가 요청을 했을 때 토큰만 확인하면 된다.

  즉 세션 관리가 필요 없어서 서버 자원을 많이 아낄 수 있다.

 

  2 - 2) 정보 교환

  JWT는 두 개체 사이에서 안정성 있게 정보를 교환하기에 좋은 방법이다.

  그 이유는, 정보가 sign 이 되어있기 때문에 정보를 보낸 이 가 바뀌진 않았는지, 또 정보가 도중에 조작되지는 않았는지 검증할 수 있다.

 

 

 

3. JWT의 구조

 

  3 - 1) header(헤더)

  Header는 두 가지의 정보를 지니고 있다.

 

  typ: 토큰의 타입 바로 JWT 이다.

  alg해싱 알고리즘을 지정한다.

 

  해싱 알고리즘으로는 보통 HMAC SHA256 혹은 RSA 가 사용되며, 이 알고리즘은, 토큰을 검증할 때 사용되는 signature 부분에서 사용된다.

 

3 - 2) payload(내용)

Payload 부분에는 토큰에 담을 정보가 들어있다.

여기에 담는 정보의 한 ‘조각’을 클레임(claim)이라고 부르고, 이는 name : value의 한 쌍으로 이뤄져 있다.

토큰에는 여러 개의 클레임 들을 넣을 수 있다.

클레임의 종류는 다음과 같이 크게 세 분류로 나뉘어있다.

 

  등록된 (registered) 클레임,
  공개 (public) 클레임,
  비공개 (private) 클레임

 

  #1 등록된 클레임

  등록된 클레임들은 서비스에서 필요한 정보들이 아닌, 토큰에 대한 정보들을 담기 위하여 이름이 이미 정해진 클레임들이다.

  등록된 클레임의 사용은 모두 선택적 (optional)이며, 이에 포함된 클레임 이름들은 다음과 같다.

  • iss: 토큰 발급자 (issuer)
  • sub: 토큰 제목 (subject)
  • aud: 토큰 대상자 (audience)
  • exp: 토큰의 만료시간 (expiraton), 시간은 NumericDate 형식으로 되어있어야 하며 (예: 1480849147370) 언제나 현재 시간보다 이후로 설정되어있어야 한다.
  • nbf: Not Before를 의미하며, 토큰의 활성 날짜와 비슷한 개념이다. 여기에도 NumericDate 형식으로 날짜를 지정하며, 이 날짜가 지나기 전까지는 토큰이 처리되지 않는다.
  • iat: 토큰이 발급된 시간 (issued at), 이 값을 사용하여 토큰의 age 가 얼마나 되었는지 판단할 수 있다.
  • jti: JWT의 고유 식별자로서, 주로 중복적인 처리를 방지하기 위하여 사용된다. 일회용 토큰에 사용하면 유용하다.

#2 공개 클레임

  공개 클레임들은 충돌이 방지된 (collision-resistant) 이름을 가지고 있어야 한다.

  충돌을 방지하기 위해서는, 클레임 이름을 URI 형식으로 짓는다.

 

#3 비공개 클레임

  등록된 클레임도 아니고, 공개된 클레임들도 아니다.

  양 측간에 (보통 클라이언트 <->서버) 협의하에 사용되는 클레임 이름들이다.

  공개 클레임과는 달리 이름이 중복되어 충돌이 될 수 있으니 사용할 때에 유의해야 한다.

 

3 - 3) 서명(signature)

  JSON Web Token의 마지막 부분은 바로 서명(signature)이다.signature) 이다.

  이 서명은 헤더의 인코딩 값과, 정보의 인코딩 값을 합친 후 주어진 비밀키로 해쉬를 하여 생성한다.

  이렇게 만든 해쉬를, base64 형태로 나타내면 된다.

 

 

 

4. JWT 생성

  이제 header, payload, signature 세 가지를 직접 인코딩하여 jwt를 만들어보자!

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
const crypto = require('crypto');
const header = {
    "typ""JWT",
    "alg""HS256"
};
const payload = {
    "iss""juveloper.com",
    "exp""1485270000000",
    "https://juveloper.com/jwt_claims/is_admin"true,
    "userId""11028373727102",
    "username""juveloper"
};
 
// encode to base64
const encodedHeader = new Buffer(JSON.stringify(header))
    .toString('base64')
    .replace('=''');
//header data 'base64'로 인코딩!
 
const encodedPayload = new Buffer(JSON.stringify(payload))
    .toString('base64')
    .replace('=''');
//payload data 'base64;로 인코딩!
 
const signature = crypto.createHmac('sha256''secret')
    .update(encodedHeader + '.' + encodedPayload)
    .digest('base64')
    .replace('=''');
//signature부분 생성!
 
console.log(`${encodedHeader}.${encodedPayload}.${signature}`);
//jwt 토큰 
cs

 

  생성된 jwt를 다시 디코딩해보자!

  https://jwt.io/

 

JWT.IO

JSON Web Tokens are an open, industry standard RFC 7519 method for representing claims securely between two parties.

jwt.io

의 디버거 기능을 통해 우리가 만들어낸 jwt를 디코딩할 수 있다!

 

디코딩된 JWT

 

 

*출처 : velopert.com/2389

'Authentication' 카테고리의 다른 글

OAuth 2.0  (0) 2020.12.04
Cookie & Session  (0) 2020.12.04

1. OAuth란?

 

  OAuth2.0이란 각종 웹, 모바일 어플리케이션에서 타사의 API를 사용하고 싶을 때 권한 획득을 위한 프로토콜(Protocol)이다.

  간단하게는 로그인에서부터 다양한 기능의 API를 안전하고 편하게 사용하게 해준다.

  많은 웹 서비스와 모바일 어플리케이션을 이용하면서 다음과 같은 문구를 많이 봤을 것이다.

 

“facebook으로 로그인”, “Google 계정으로 로그인”, “Naver로 로그인”

 

  이러한 기능으로 이용하고자 하는 서비스에 대한 회원가입 과정을 거치지 않고 기존에 사용하던 서비스들의 계정으로 로그인을 진행할 수 있다. 이것이 OAuth2.0의 장점이다. 특히 회원가입과 같은 절차는 고객의 개인정보를 다루는 일이므로 고객뿐만 아니라 서비스를 제공하는 회사입장에서도 부담스러운 일이 아닐 수가 없다.

 

간단하게 과정을 살펴본다면 위의 버튼들을 클릭하여 로그인을 진행하다보면 타사 서비스(Google, facebook)에 로그인이 되어있지 않다면 먼저 로그인을 요구하는 입력창이 나올 것이고, 로그인을 한 후에는 권환 획득에 관한 수락을 요구하는 창이 뜰 것이다. 이러한 과정들을 거쳐 로그인에 성공하게 된다.

 

 

2. OAuth의 장점

 

  2 - 1) 위에서 언급했듯이 서비스마다 회원가입을 할 필요없이 기존의 사용하던 타사의 정보를 이용하여 로그인을 진행할 수 있다.

 

  2 - 2) 보안이 우수한 타사의 계정을 이용하여 직접 타사의 아이디와 비밀번호를 입력하던 예전 방식보다 안전한 사용을 제공한다.

 

  2 - 3) 정보는 회원 정보뿐만 아니라 기타 API에 대한 정보에도 접근이 가능한다.

 

  이렇게 사용자들이 타사에서 사용하고 있는 서비스들에 대한 정보를 가져와 가공하여 보다 가치있는 결과물을 사용자들에게 제공할 수 있습니다. 가장 많이 이용되는 것은 바로 타사의 인증된 회원정보를 통한 로그인입니다.

 

 

 

3. Auth의 의미

 

  Authentication 와 Authorization

 

  3 - 1) Authentication : 인증

 

  3 - 2) Authorization : 허가

 

OAuth2.0은 타사 서비스(Google, facebook)의 기능에 우리가 만든 서비스의 접근을 허락(Authorization)하여 사용자를 인증 (Authentication)한다.

 

 

 

4. OAuth를 이용한 Authorization 과정

 

용어 의미
Client 우리가 만든 서비스(웹, 앱 애플리케이션)
Resource Server 기능을 제공하는 타사(Google, Facebook)
Resource Owner 우리가 만든 서비스를 이용하려는 사용자

 

  4 - 1) 먼저 우리가 만든 Client가 Resource Server의 API를 사용한다고 Resource Server에 등록을 해야한다.

  

출처 : https://baked-corn.tistory.com/m/29

  등록을 하게 되면 Resource Server는 이 Client를 식별할 수 있는 Client ID와 Client Secret을 발급한다.

 

 

 

  4 - 2) 이 후 Resource Owner가 우리가 만든 Client에서 Google 계정으로 로그인을 통해 로그인을 요청한다.

 

출처 : https://baked-corn.tistory.com/m/29

 

 

 

  4 - 3) Client는 Resource Owner에게 Resource Server의 로그인 창을 띄어준다.

 

출처 : https://baked-corn.tistory.com/m/29

 

 

  4 - 4) Resource Owner는 Client가 Resource Server에 있는 자신의 정보의 접근에 대한 동의를 구하는 창을 보고 동의를 하게 된다.

 

출처 : https://baked-corn.tistory.com/m/29

 

  즉 해당 서비스가 사용자의 Google 로그인 정보에 대해 접근을 허락하는지 안하는지에 대해 결정하는 과정이다.

  이 과정에서 수락을 하지 않는다면 정보가 제공되지 않기 때문에 로그인은 할 수 없다.

 

 

  4 - 5) 만일 Resource Owner가 Client에게 Resource Server에 있는 자신의 정보에 접근을 허락하면 Resource Server는 Client에게 일련의 암호화된 코드를 제공하고 이 코드와 함께 해당 정보의 사용 등록을 했는지의 여부를 판단하는 Client ID와 Client Secret을 함께 보내 모든 것이 일치한다면 최종 접근 권한 부여의 암호인 Access Token을 발급하게 된다.

 

출처 : https://baked-corn.tistory.com/m/29

 

 

 

5. 요약

 

  이러한 Authorization의 과정을 걸쳐 Client는 Resource Server의 특정 정보에 대한 접근 권한을 얻게 된다.

  또한 해당 정보를 토대로 Resource Owner를 인증(Authentication)하여 Client의 서비스를 이용할 수 있게 한다.

  이렇게 OAuth2.0을 사용하면 보다 편리하고 안전하게 여러 검증된 API를 사용할 수 있으며 사용자의 편의성도 높일 수 있다.

 

 

 

출처 : https://baked-corn.tistory.com/m/29

'Authentication' 카테고리의 다른 글

JWT  (0) 2020.12.15
Cookie & Session  (0) 2020.12.04

1. 쿠키란 무엇일까?

 

쿠키의 발급과정, 출처 : https://interconnection.tistory.com/m/74

 

  1 - 1) 쿠키는  브라우저에 키와 값의 형태로 저장되는 작은 데이터 파일이다.

 

  1 - 2) 쿠키의 구성요소는 키, 값, 유효 시간, 도메인 이름, 경로 등이 있다.

           유효 시간을 명시하면 브라우저가 종료되더라도 명시한 기간동안 쿠키는 사라지지 않는다.

           도메인 이름과 경로는 특정 도메인과 경로에서만 쿠키를 사용하도록 하는 옵션이다.

 

  1 - 3) Response Header에 Set-Cookie 속성을 사용하면 클라이언트에 쿠키를 만들 수 있다.

 

  1 - 4) 쿠키는 만들어지기만 하면 브라우저가 자동으로 Request 시에 header에 넣어 서버에 전송한다.

            물론 요청을 보내는 엔드포인트가 만들어진 쿠키의 옵션의 조건에 부합하는 경우만이다.

 

 

 

2. 쿠키는 왜 필요한가?

 

  HTTP 통신 방식은 두 가지 특징을 가지고 있다.

  

  2 - 1) Conectionless

    클라이언트가 요청을 한 후 응답을 받으면 그 연결을 끊어 버리는 특징
    HTTP는 먼저 클라이언트가 request를 서버에 보내면, 서버는 클라이언트에게 요청에 맞는 response를 보내고 접속을 끊는 특성

  

  2 - 2) Stateless

    통신이 끝나면 상태를 유지하지 않는 특징
    연결을 끊는 순간 클라이언트와 서버의 통신이 끝나며 상태 정보는 유지하지 않는 특성

 

  이러한 두 가지 특성으로 쿠키가 필요한 것이다.

  예를 들어, 어떤 사용자가 웹 애플리케이션을 이용하기위해 로그인을 했다.

  만약 로그인을 했다는 정보가 저장되지 않는다면 해당 사용자는 웹 페이지를 이동할 때마다 매번 로그인을 해야할 것이다.

 

 

 

3. 쿠키 옵션

 

  • Domain쿠키 옵션에서 도메인은 포트 및 서브 도메인 정보, 세부 경로를 포함하지 않는다.따라서 요청해야 할 URL이 http://www.localhost.com:3000/users/login 이라 하면 Domain은 localhost.com이 된다.
  • 만약 쿠키 옵션에서 도메인이 존재한다면 클라이언트에서는 쿠키의 도메인과 서버의 도메인이 일치해야만 쿠키를 전송할 수 있다.
  • 여기서 서브 도메인이란 www 같은 도메인 앞에 추가로 작성되는 부분을 말한다.
  • 도메인이라는 것은 여러분들이 흔하게 보실 수 있는 www.google.com과 같은 서버에 접속할 수 있는 이름이다.
  • Path만약 요청해야 하는 URL이 http://www.localhost.com:3000/users/login 인 경우라면 여기에서 Path,
    Path 옵션의 특징은 설정된 path를 전부 만족하는 경우 요청하는 Path가 추가로 더 존재하더라도 쿠키를 서버에 전송할 수 있다.
  • 즉 Path가 /users로 설정되어 있고, 요청하는 세부 경로가 /users/login 인 경우라면 쿠키 전송이 가능하다.
  • 명시하지 않으면 기본으로 / 으로 설정되어 있다.
  • 세부 경로는 /users/login이 된다.
  • 경로는 서버가 라우팅할 때 사용하는 경로다.
  • MaxAge or ExpiresMaxAge는 앞으로 몇 초 동안 쿠키가 유효한지 설정하는 옵션이다.이후 지정된 시간, 날짜를 초과하게 되면 쿠키는 자동으로 파괴된다.
  • 하지만 두 옵션이 모두 지정되지 않는 경우에는 브라우저의 탭을 닫아야만 쿠키가 제거될 수 있다.
  • Expires 은 MaxAge와 비슷하다. 다만 언제까지 유효한지 Date를 지정한다. 이때 클라이언트의 시간을 기준으로 한다.
  • 쿠키가 유효한 기간을 정하는 옵션이다.
  • Secure 쿠키를 전송해야 할 때 사용하는 프로토콜에 따른 쿠키전송 여부를 결정한다. 만약 해당 옵션이 true로 설정된 경우, 'HTTPS' 프로토콜을 이용하여 통신하는 경우에만 쿠키를 전송 할 수 있다.
  • HttpOnly만약 해당 옵션이 true로 설정된 경우, 자바스크립트에서는 쿠키에 접근이 불가능하다.만약 이 옵션이 false인 경우 자바스크립트에서 쿠키에 접근이 가능하므로 'XSS' 공격에 취약하다.
  •  
  • 명시되지 않는 경우 기본으로 false로 지정되어 있다.
  • 자바스크립트에서 브라우저의 쿠키에 접근 여부를 결정한다.
  • SameSite사용 가능한 옵션은 다음과 같다.
    • Lax :Cross-Origin 요청이면 'GET' 메소드에 대해서만 쿠키를 전송할 수 있다.
    • Strict : Cross-Origin이 아닌 same-site 인 경우에만 쿠키를 전송 할 수 있다.
    • None: 항상 쿠키를 보내줄 수 있습니다. 다만 쿠키 옵션 중 Secure 옵션이 필요합니다.
    이때 'same-site'는 요청을 보낸 Origin과 서버의 도메인이 같은 경우를 말한다.
  • Cross-Origin 요청을 받은 경우 요청에서 사용한 메소드와 해당 옵션의 조합으로 서버의 쿠키 전송 여부를 결정하게 된다.

    이러한 옵션들을 지정한 다음 서버에서 클라이언트로 쿠키를 처음 전송하게 된다면 헤더에 Set-Cookie라는 프로퍼티에 쿠키를 담아 쿠키를 전송하게 된다.

 

    이후 클라이언트 혹은 서버에서 쿠키를 전송해야 한다면 클라이언트는 헤더에 Cookie라는 프로퍼티에 쿠키를 담아 서버에 쿠키를 전송하게 된다.

 

 

4. Session

 

  4 - 1) 세션은 쿠키를 기반하지만, 해당 데이터를 브라우저에 저장하는 쿠키와 달리 서버에 저장한다.

 

  4 - 2) 서버에서는 클라이언트에게 고유한 세션 ID를 부여해 클라이언트를 식별한다.

 

  4 - 3) 기본적으로 웹 브라우저가 서버에 접속해서 브라우저를 종료할 때까지 인증상태를 유지한다.

 

  4 - 4) 사용자의 정보를 서버에 저장한다는 점에서 쿠키보다 보안성은 좋지만, 사용자가 많아질수록 서버에 과부하가 걸릴 수도 있다.

 

 

 

5. Session의 동작 방식  

 

  5 - 1) 클라이언트가 서버에 접속 시 세션 ID를 발급받는다.

 

  5 - 2) 클라이언트는 세션 ID에 대해 쿠키를 사용해 브라우저에 저장한다.

 

  5 - 3) 클라이언트는 서버에 요청할 때, 이 쿠키의 세션 ID를 서버에 전달한다.

 

  5 - 4) 서버는 세션 ID를 전달 받아 서버에 저장된 세션 ID와 일치하는지 확인하고 세션에 있는 클라이언트 정보를 가져온다.

 

  5 - 5) 클라이언트 정보를 가지고 서버 요청을 처리하여 클라이언트에게 응답한다.

 

 

 

6. 쿠키와 세션의 차이

 

  6 - 1) 쿠키와 세션은 비슷한 역할을 하며, 동작원리도 비슷하다. 그 이유는 세션도 결국 쿠키를 사용하기 때문이다.

 

  6 - 2) 가장 큰 차이점은 사용자의 정보가 저장되는 위치다. 쿠키는 서버의 자원을 전혀 사용하지 않으며, 세션은 서버의 자원을 사용한다.

            보안 면에서 세션이 더 우수하며, 요청 속도는 쿠키가 세션보다 더 빠르다. 그 이유는 세션은 서버의 처리가 필요하기 때문이다.

 

  6 - 3) 쿠키는 클라이언트 로컬에 저장되기 때문에 변질되거나 request에서 스니핑 당할 우려가 있어 보안에 취약하다.

           하지만 세션은 쿠키를 이용해 session_id 만 저장하고 그것으로 구분해서 서버에서 처리하기 때문에 비교적 보안성이 좋다.

 

  6 - 4) 라이프 사이클, 쿠키도 만료시간이 있지만 파일로 저장되기 때문에 브라우저를 종료해도 계속해서 정보가 남아 있을 수 있다.

          또한 만료기간을 넉넉하게 잡아두면 쿠키삭제를 할 때 까지 유지될 수도 있다.

 

  6 - 5) 반면에 세션도 만료시간을 정할 수 있지만 브라우저가 종료되면 만료시간에 상관없이 삭제된다.

 

 

 

7. 캐시와 엄연히 다르다!

 

  캐시는 정적파일을 브라우저나 서버 앞 단에 저장해놓고 사용하는 것이다.

  한번 캐시에 저장되면 브라우저를 참고하기 때문에 서버에서 변경이 되어도 사용자는 변경되지 않게 보일 수 있다.

  이런 부분은 캐시를 지워주거나 서버에서 클라이언트로 응답을 보낼 때 header에 캐시 만료시간을 명시하는 방법등을 이용할 수 있다.

 

 

 

*출처 : interconnection.tistory.com/m/74

'Authentication' 카테고리의 다른 글

JWT  (0) 2020.12.15
OAuth 2.0  (0) 2020.12.04

+ Recent posts