Strapi 서버에서 JWT(JSON Web Token) 발급받기.

y0knono·2021년 3월 25일
0

Strapi

목록 보기
1/2
post-thumbnail

 웹 어플리케이션에 로그인 기능을 구현해야 한다. 아무리 생각해도 대충 하면 안될것 같다. 보안적으로 너무 안일하게 만들 수는 없다는 생각에 열심히 검색한 결과, Json Web Token을 써야겠다는 판단이 들었다.

 공부 차원에서 논리의 흐름을 정리하자면, 일단 비밀번호는 최초의 로그인 시에만 사용되어야 한다. 이를 계속 가지고 있다는 것은 그만큼 위험한 짓이다. 그렇다면, '사용자가 GUI상에서 입력 받은 직후 더이상 패스워드를 가지고 있으면 안된다.' 라는 기준을 부합해야 한다. 다양한 방법이 있지만, 웹 표준(RFC 7519)에 맞는 것을 적용하는 것이 낫겠다 생각하여 JWT를 쓰기로 판단했다.

 그러니까 최초로 권한을 인증 받은 시한적인 토큰을 인증수단으로 삼으면, 서버는 부하를 줄일 수 있고, 그 토큰을 사용자는 request 할 때마다 같이 보내서 인증 받는다는 개념으로 이해했다.

이 기술은 홈페이지가 있다. https://jwt.io 영잘알은 비루한 내 글보다 이게 낫다.

Token 구조

 곤충처럼 총 세 부위로 나뉜다. 인코딩 된 토큰에서는 부위 사이에 점이 있다.

#HEADER
{
   "alg": "HS256",
   "typ": "JWT"
}

#PAYLOAD
{
   "sub": "1234567890",
   "name": "John Doe",
   "iat": 1516239022
}

#VERIFY SIGNATURE
HMACSHA256(
   base64UrlEncode(header) + "." +
   base64UrlEncode(payload),
   your-256-bit-secret
)

머리(Header).내용(PAYLOAD).서명(VERIFY SIGNATURE)

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c

특징

  1. 서버 기반 인증형태에 비해 서버 부하가 줄어든다.
  2. 권한을 잘 구분해서 필요없는 부분을 나눠야 한다. 단 하나의 문자를 보내야 할 때도 토큰을 같이 보내야 하니까.
  3. 어디에 저장하느냐에 따라 보안 문제가 생긴단다. 웹 스토리지에 저장하지 말고 httpOnly를 지정받은 Cookie로 저장하여 사용하는게 XSS 공격을 막을 수 있다.
  4. 쿠키로 저장 시 CSRF 공격에 취약점이 있다. 하지만 나는 내공이 부족하여 이에 대한 적용은 다음에 추가적으로 해 볼 예정이다.

구현

  1. 예제에 사용할 id를 strapi user Collection Type에 만들어 주자.
    일단 Strapi는 JWT 발급이 기본적으로 된다. 추후 CSRF를 막기 위해 Strapi 프로젝트 내에 JWT Validator를 넣어 줘야 하는 것을 기억하자. 참고
    다른 API를 작성하였다면 따로 발급 시스템을 작성해야 한다.

  2. 일단 간단히 react-create-app 에다가 예제 작성

./api/auth/Auth.jsx

import React from 'react';
import axios from 'axios';

export Auth () => {
  const login = async (id, password) => {
    const { data } = await axios.post('http://서버아이피:포트/auth/local', {
      identifier: id,
      password: password,
    })
    console.log(data.jwt);
  }
  login('예제로만든 아이디','비밀번호');
}
export default Auth.jsx;

App.jsx

import logo from './logo.svg';
import './App.css';
import Auth from './api/auth/Auth';

function App() {
  return (
    <div className="App">
      <header className="App-header">
        <img src={logo} className="App-logo" alt="logo" />
        <Auth/>
      </header>
    </div>
  );
}
export default App;


콘솔에 나오는 것을 확인했다. 다음 포스팅에서 쿠키에 저장하는 법을 다루도록 하겠다.

참고 사이트 : https://backend-intro.vlpt.us/4 (개념 설명이 잘 되어 있다.)

profile
모르니까 노력하는 중

0개의 댓글