Installation Packages
npm install axios
npm install jsonwebtoken
npm install express
라이브러리 설치
이외에 쿠키 설정할 때 잘 되지 않는다면 Cookie parser 미들웨어를 사용하고
환경변수를 사용하기 위해서는 dotenv 미들웨어를 사용하면됩니다.
SecretKey
인터넷에서 해쉬 생성기를 통해 임의로 생성하거나
Crypto 라이브러리를 이용해 임의의 SecretKey를 생성하고
일반적으로 .env파일에 환경변수로 저장하여 사용합니다.
Login Page, ReactJS
import React from 'react';
import axios from 'axios';
import { useRef } from 'react';
const Login : React.FC = () => {
const url = process.env.REACT_APP_NODE_URL;
const usernameRef = useRef<HTMLInputElement>(null);
const passwordRef = useRef<HTMLInputElement>(null);
const handleLogin = (e: React.FormEvent) => {
if (usernameRef.current && passwordRef.current) {
const username = usernameRef.current.value;
const password = passwordRef.current.value;
e.preventDefault()
try {
axios.post(url + '/api/login', {
id: username,
pw: password,
},
{ withCredentials: true }
).then(response => {
if (response.data) {
alert('Login Success!');
localStorage.setItem('accessToken', response.data.accessToken);
} else {
alert('Invalid ID or PW!');
}
});
} catch(err) {
console.log(err);
}
}
}
return (
<div>
<h2>Login Page</h2>
<form>
<input type="text" placeholder="Username" ref={usernameRef}/>
<br/>
<input type="password" placeholder="Password" ref={passwordRef}/>
<br/>
<button onClick={handleLogin}>Login</button>
<br/>
</form>
</div>
)
}
export default Login;
ID 및 PW를 입력받고 제출할 수 있는 간단한 HTML 코드를 입력합니다.
또한 비동기 요청으로 Login API를 요청하여 ID 와 PW를 전달하여
백엔드에서 토큰을 발급받고 AccessToken은 localStrorage에 set합니다.
Login API, NodeJS
const express = require('express');
const { generateAccessToken, generateRefreshToken } = require('../../module/login/jwtUtil');
const router = express.Router();
router.use(express.json());
const users = {
user1: 'password1',
user2: 'password2',
user3: 'password3',
}
router.post('/', (req, res) => {
const { id, pw } = req.body;
if (users[id] && users[id] === pw) {
const accessToken = generateAccessToken(id);
const refreshToken = generateRefreshToken(id);
res.cookie('refreshToken', refreshToken, {
secure: false,
httpOnly: true,
sameSite: 'Strict',
maxAge: 14 * 24 * 60 * 60 * 1000,
});
res.json({ accessToken });
} else {
res.send(false);
}
});
module.exports = router;
require('dotenv').config();
const jwt = require('jsonwebtoken');
const accessKey = process.env.ACCESS_SECRET_KEY;
const refreshKey = process.env.REFRESH_SECRET_KEY;
function generateAccessToken (id) {
const payload = {
id: id,
permission: ['write'],
}
return jwt.sign(payload, accessKey, {
algorithm: 'HS256',
expiresIn: '1m',
});
}
function generateRefreshToken (id) {
const payload = {
id: id,
}
return jwt.sign(payload, refreshKey, {
algorithm: 'HS256',
expiresIn: '14d',
});
}
function verifyAccessToken (receivedToken) {
try {
const decoded = jwt.verify(receivedToken, accessKey);
// db query
return {
success: true,
id: decoded.id,
}
} catch(err) {
console.log(err);
return {
success: false,
id: null,
}
}
}
function verifyRefreshToken (receivedToken) {
try {
const decoded = jwt.verify(receivedToken, refreshKey);
// db query
return {
success: true,
id: decoded.id,
}
} catch(err) {
console.log(err);
return {
success: false,
id: null,
}
}
}
module.exports = {
generateAccessToken,
generateRefreshToken,
verifyAccessToken,
verifyRefreshToken,
}
JTW 라이브러리를 통해 토큰을 생성하고
API 요청이 왔을 때 Cookie를 통해 refreshToken
response를 통해 accessToken을 응답합니다.
여기까지 준비되었다면
리액트 프로젝트를 빌드하여 서버를 실행시키고 F12를 눌러 Application Tab으로 이동해봅시다
마무리
여기까지 간단하게 클라이언트 단에서 로그인을 통해 토큰을 요청하고
토큰을 발급하는 실습을 해보았습니다.
실습을 통해 JWT에 대한 개념들이 명확해지는 것을 느끼게 됩니다.
클라이언트는 Token이라는 열쇠를
서버는 SecretKey라는 자물쇠라 생각하면 이해하기 쉬울 것 같습니다.
Node에서 환경변수도 Cookie도 처음 써보는 개념이라 생소하고 미들웨어 이슈들로 인해 계속 막혔지만
하나하나 검색하면서 실습해가니,, 어찌저찌 성공하게 되는 것 같습니다.
오래 걸리더라도 직접 찾고 검색하니 나의 지식이 되는게 쨩쨩입니다,,
다음에는 이 토큰을 가지고 상태관리 라이브러리를 통해 로그인 상태를 관리하고
refreshToken을 통해 만료된 accessToken을 재발급 받고 확인하는 과정을 실습해봅시다
'Web' 카테고리의 다른 글
Edge, IEMode 설정, Internet Explorer (0) | 2024.08.06 |
---|---|
Input Tag가 Click, Focus 되지 않을 때 (0) | 2024.07.22 |
JWT, NodeJS와 React를 통해 구현해보기 (1) (0) | 2024.06.28 |
Domain 구매 및 로컬 PC 연결 (0) | 2024.04.30 |
HTML, Input 파일탐색기, Finder FileFormat 지정 (0) | 2024.04.16 |