우리가 웹사이트를 이용하다 보면 '세션이 만료되어 로그아웃 되었습니다.' 혹은 ' 세션이 만료되었습니다. 다시 로그인 후 시도해 주세요.'와 같은 문구를 만날 수 있는데요 이는 곧 로그인이 풀렸다는 뜻이 됩니다.
인증 Authentication
인증은 곧 로그인을 이야기 합니다. 그렇다면 우리가 로그인이 필요할 때가 언제가 있을까요?
쇼핑몰 이용시 장바구니 이용할 때
쇼핑몰 상품을 구매할 때
마이페이지 들얼갈 때
즉 사이트에서 가입되어있는 유저만 이용할 수 있는 기능을 이용할 수 있게 도와줄 수 있는 것을 말합니다.
인가 Authorization
가입되어있는 사람들 중에서도 관리자와 일반유저를 나눠서 접근 페이지가 다를 때 해당 페이지에 접근 권한이 존재하는가를 확인할 때 사용하는 것을 말합니다.
관리자 : 상품관리/ 상품등록
일반유저 : 상품페이지
정리를 하자면 인증은 관리자든 고객이든 인증을 통해서 사이트에 가입된 사용자를 증명하는것을 말하고, 인가는 인증 후에 사용자가 특정페이지에 접근 권한이 있는지 확인하는 것을 말합니다.
그렇다면 인증은 동작 하나하나 할 때마다 하게 되는 걸까요? 아닙니다. 한번 로그인을 하면 일정시간을 유지할 수 있게 만들어 사이트를 이용하는데 불편함이 없게 해 주는데 그 로그인을 인증하는 것이 바로 [쿠기, 세션, JWT]입니다.
로그인 인증
쿠키 Cookie
로그인을 하면 서버가 쿠키에 사용자 정보를 넣어 전달해주면 이후 사용자 인증이 필요할 때마다 쿠키를 서버에 다시 전달해 주면서 로그인을 유지시키는 것입니다. 즉, 사용자-서버 간의 쿠키를 계속 전달해주는 것을 말하는데요. 그렇다면 이 쿠키는 왜 사용하는 걸까요?
장점 : 서버가 저장하지 않음
→ 서버의 저장공간을 아낄 수 있습니다.
→ HTTP의 stateless 조건을 충족시킵니다 = RESTful 하다
단점 : 보안에 취약
세션 Session
쿠키의 단점을 보안하기 위한게 바로 Session인데요. 바로 중요한 정보는 서버에 저장을 하고 서버에 저장된 ID값만 쿠키로 전달하여 해당 아이디값을 사용자-서버 간에 계속 전달을 하는 것입니다.
장점 : 보안이 비교적 강해졌습니다
단점 : 서버에 저장이 됩니다.
→ 서버의 저장공간을 사용한다.
→ HTTP의 stateless 조건을 불충족시킵니다 = RESTful 하지 않다.
즉 쿠키와 세션은 서로가 단점을 보완하고자 만들어졌지만 그 보완 때문의 각자의 장점이 단점이 된 것입니다.
JWT (JSON Web Token)
웹에서 사용하는 json 형태의 데이버를 안전하게 전송하는 토큰을 말합니다.
토큰은 로그인을 하여 사이트 유저임을 인증하는 인증용으로 사용하기도 하지만 토큰 데이터 정보에는 사용자의 권한까지 확인하는 인가용으로도 사용합니다. 즉 토큰을 가진 사용자가 증명을 하기 위한 수단이라고 할 수 있습니다.
장점
→ 보안에 강하다 (= 암호화가 되어있다)
→ 서버가 상태를 저장하지 않습니다 = Stateless조건 충족 = RESTful 하다
→ 서버 부담을 줄일 수 있습니다. cf. 토큰을 발행하는 서버를 따로 만들어 줄 수도 있음.
JWT 구조
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0 IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
이게 바로 JWT입니다. JWT는 단순하게 한 줄인 것처럼 보이지만 사실은 3가지 구역으로 나뉘어 있습니다. 바로. 을 통해 연결을 한 것입니다. 사진을 보면 아시겠지만 오른쪽 부분은 우리가 알아볼 수 있는구 조지만 왼쪽 부분은 우리가 알아볼 수 없는 구조인걸 아시겠죠? 왼쪽 부분은 Encoded , 암호화된 상태를 말합니다. 그렇다면 Decoded, 복호화한다면 어떤 내용을 담고 있을까요?
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9
.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ
.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
Encoded 된 상태를 세 구역으로 나누면 이런 모양이 됩니다. 각각 복호화했을 때 의미하는 것을 알아봅시다.
첫 번째 줄은 바로 HEADER입니다. 암호화할 때 사용한 알고리즘*과 토큰타입(형태)을 작성한 곳입니다.
두 번째 줄은 PAYLOAD입니다. 즉 사용자의 data정보(이름, 주소, 핸드폰,.... 비밀번호 x)를 작성한 곳입니다.
마지막 세 번째 줄은 VERIFY SIGNATURE 부분입니다. 해당 토큰의 서명을 작성한 부분인데 이는 보안과 직결된 부분입니다.
암호화 알고리즘
암호화하는 데 사용되는 알고리즘은 다양한 형태가 있는데 어떤 알고리즘을 사용했는가에 따라 Encoded 값이 달라질 수 있습니다.
JWT를 빼서 데이터 값을 바꾸면?
의문이 생길 수 있다고 생각합니다. JWT를 빼서 데이터값을 변경하면 이용가능하지 않을까? 하지만 이를 막아주는 것이 바로 마지막 verify signature입니다. 제일 처음 생성한 token에서 payload 부분을 변경하면 payload 암화만 바뀌는 게 아니라, verify signature의 암호화 부분도 바뀌기 때문에 payload를 변경하면 완전히 다른 토큰이 되는 것이고 때문에 우리는 JWT를 믿고 쓸 수 있게 된 것입니다.
JWT로 인증/인가 절차 확인하기
JWT 사용하기
npm install jsonwebtoken
토큰 생성
const jwt = require('jsonwebtoken');
const token = jwt.sign({
name : 'code dung'
}, private key)
jwt 를 사용하는것은 아주 간단합니다. require을 통해서 jsonwebtoken을 가져온 뒤에 sign 함수를 사용하는것입니다. sign함수 안에는 payload = 유저의 데이터와, private key를 입력을 해주면 기본적으로 jwt 발급을 마친 상태가 됩니다.
그렇다면 만든 token을 어떻게 확인을 할까요? 그냥 console.log(token)을 하게 되면 암호화되어있는 code가 나오는데요. 우리는 이걸 복호화하는 작업을 통해서 token안의 정보를 받아 볼 수 있습니다.
토큰 복호화
const decoded = jwt.verify(token, private key)
verify 함수를 통해서 토큰의 복호화를 진행하여 안에 들어있는 user의 data 값을 받을 수 있습니다. 이 data값으로 서버에 정보가 일치하는지를 확인 할 수 있는것이죠
'개발지식' 카테고리의 다른 글
컴파일 언어와 스크립트 언어 (0) | 2024.01.22 |
---|---|
동기와 비동기, 블로킹과 논블로킹 (0) | 2024.01.11 |
env 환경변수 (0) | 2023.12.25 |
code refactoring (0) | 2023.12.12 |
라이브러리와 프레임워크 (0) | 2023.12.05 |