ํ ํฐ์ ๋ฐ๊ธํ๊ณ ์ธ์ฆ๋ฐ๊ณ , ๊ฒ์ฆํ๋ ค๋๋ฐ ๊ตฌ์กฐ์ ํ๋ก์ธ์ฑ์ ์ดํดํ๋๋ฐ 5์ผ์ด ๊ฑธ๋ฆฐ ๊ฑฐ ๊ฐ๋ค...
๊ฐ๋ฐ๋ ์๋ก ํฐ์คํ ๋ฆฌ์ ๋ด์ฉ ๋ฐ ์ฝ๋๊ฐ ๋ณ๊ฒฝ๋ ์ ์์ต๋๋ค.
์ฐธ๊ณ ์ฌ์ดํธ
- ๊ตฌ๊ธ ๊ฒ์์ผ๋ก "jwt", "token" ์ธ์ฆ ๊ด๋ จ ๊ฒ์์ผ๋ก ๋์จ ๋ด์ฉ ์ ๋ถ
๐ง ์ฌ์ ์ง์
const jwt = require('jsonwebtoken');
//
// ํ ํฐ ๋ฐ๊ธ ์ฝ๋
//
// Data - ํ ํฐ์ ๋ด์ ๋ด์ฉ์ ๋ด์ต๋๋ค.
// SecretKey - ์์์ ์ผ๋ก ๊ฐ๋ฐ์๊ฐ ์ ํด์ค๋๋ค.
// options - ํ ํฐ์ ์ ํจ๊ธฐ๊ฐ ๋ฐ ์๋ช
์ต์
์ ์ง์ ํ์ต๋๋ค.
const token = jwt.sign(Data<jwtContent>, SecretKey, signOptions )
//
// ํ ํฐ ๊ฒ์ฆ ์ฝ๋
//
// token - ๋ฐ๊ธ ๋ฐ์ ํ ํฐ์ ๋ด์ต๋๋ค.
// SecretKey - ๋ฐ๊ธ ์์ ์ฌ์ฉํ SecretKey๋ฅผ ๋ฃ์ต๋๋ค.
// Callback - ๊ฒ์ฆ์ ๋ํ ๊ฒฐ๊ณผ๋ฅผ ๋ํ๋ด๋ ํจ์๋ฅผ ์ฝ์
ํฉ๋๋ค.
const isVerified = jwt.verify(token, SecretKey, Callback);
โข jwt.sign()์ ์ด์ฉํ์ฌ ํ ํฐ์ ๋ฐ๊ธํ๋ค.
โข jwt.verify()๋ฅผ ์ด์ฉํ์ฌ ํ ํฐ์ ๊ฒ์ฆํ๋ค.
์ด๋, ํ ํฐ์ด ์ด๋ป๊ฒ ๊ฒ์ฆ๋๋ ๊ฒ์ธ์ง ๊ณ์ ๊ถ๊ธํ๋ค.
bcrypt๋ฅผ ๊ณต๋ถํ ์งํ๋ผ ์ด๋ ํ ๊ธฐ์ค ๊ฐ(Refresh-Token)๊ณผ ๋น๊ตํ์ฌ ์ ํจ์ฑ์ ๊ฒ์ฌํ๋ ์ค ์์์ง๋ง, ๊ทธ๋ ์ง ์์๋ค.
์๋ช
์ ๋ฐ๊ธ์๋ฅผ ํ์ธํ๋ค๋๋ฐ, ์ฌ์ดํธ์ ์ธ์ฆ๋ ๋ฐ๊ธ์์ธ ๊ฒ์ ์ด๋ป๊ฒ ํ์ธํ๋์ง - ๋๋ฅผ ๊ตฌ๋ถํ๊ธฐ ์ํด์๋ SecretKey๊ฐ ์ ๋ถ์ธ๋ฐ...
GPT์๊ฒ ์ง๋ฌธํด๋ณด์๋ค.
๐ง๐ป Refresh-Token๊ณผ ๋น๊ตํ์ฌ ๋ฐ๊ธ๋ Access-Token์ ๊ฒ์ฆํ๋๊ฑฐ์ผ?
๐ค ํ ํฐ์ ๊ฒ์ฆํ ๋, access_token๊ณผ refresh_token์ ์๋ก ๋น๊ตํ๋ ๊ฒ์ ์ผ๋ฐ์ ์ผ๋ก ์ฌ์ฉ๋์ง ์์ต๋๋ค. ๋์ , access_token์ ์ ํจ์ฑ์ ํ์ธํ๊ณ ๋ง๋ฃ๋์๋์ง ํ์ธํ ํ, ๋ง๋ฃ๋ ๊ฒฝ์ฐ์๋ง refresh_token์ ์ฌ์ฉํ์ฌ ์๋ก์ด access_token์ ๋ฐ๊ธํ๋ ๋ฐฉ์์ด ์ผ๋ฐ์ ์
๋๋ค.
- ์๋ช ํ์ธ: ์๋ฒ๋ ๋ฐ์ access_token์ ์๋ช ์ ํ์ธํ์ฌ ํด๋น ํ ํฐ์ด ์ ๋ขฐํ ์ ์๋ ๋ฐ๊ธ์์์ ๋ฐ๊ธ๋์๋์ง ํ์ธํฉ๋๋ค.
- ์ ํจ ๊ธฐ๊ฐ ํ์ธ: ์๋ฒ๋ ํ ํฐ์ ์ ํจ ๊ธฐ๊ฐ์ ํ์ธํ์ฌ ํ ํฐ์ด ๋ง๋ฃ๋์๋์ง ํ์ธํฉ๋๋ค.
- ๊ถํ ํ์ธ: ์๋ฒ๋ ํ ํฐ์ ํฌํจ๋ ์ฌ์ฉ์์ ๊ถํ ์ ๋ณด๋ฅผ ํ์ธํ์ฌ ํด๋น ์์ฒญ์ด ํ์ฉ๋๋์ง ํ์ธํฉ๋๋ค.
- ๊ธฐํ ์ฌ์ฉ์ ์ ์ ๊ฒ์ฆ: ํ์์ ๋ฐ๋ผ ์ถ๊ฐ์ ์ธ ์ฌ์ฉ์ ์ ์ ๊ฒ์ฆ์ ์ํํ ์ ์์ต๋๋ค. ์๋ฅผ ๋ค์ด, ํน์ ์ฌ์ฉ์์ ์ํ๋ฅผ ํ์ธํ๊ฑฐ๋, ํน์ ์์ฒญ์ ๋ํ ๊ถํ์ ๊ฒ์ฌํ ์ ์์ต๋๋ค.
jwt.verify() ํจ์๋ฅผ ์ฌ์ฉํ๋ฉด ์์์ ์ค๋ช
ํ 1~4๋ฒ์ ๊ณผ์ ์ ํ ๋ฒ์ ์ํํ ์ ์์ต๋๋ค. jwt.verify() ํจ์๋ ๋ฐ์ ํ ํฐ์ ๋์ฝ๋ฉํ๊ณ , ์๋ช
์ ํ์ธํ๋ฉฐ, ์ ํจ ๊ธฐ๊ฐ์ ๊ฒ์ฌํ๊ณ , ํ์ํ ๊ฒฝ์ฐ ์ฌ์ฉ์ ์ ์ ๊ฒ์ฆ๋ ์ํํ ์ ์์ต๋๋ค.
๊ฒฐ๋ก ์ ์ฐ์ ์ฝ๋๋ฅผ ์์ฑํด๋ณด๊ณ ํ๋ํ๋ ํ
์คํธํด๋ณด์์๋ค.
์์ฑํ๋ ์์ ๊ธฐ์ค, SecretKey๊ฐ ์ผ์นํ๋ฉด ๋ฌธ์ ๊ฐ ์๋ ๊ฒ์ผ๋ก ๋ณด์ธ๋ค.
2024. 03. 09 ์์
๊ณ ๋ฏผํ๊ณ ์์ ๋
์ ํ๋ธ ์ํ์ฝ๋ฉ์์ jwt๊ฐ์๋ฅผ ์ฌ๋ ค์ฃผ์
จ๋ค.
https://www.youtube.com/watch?v=36lpDzQzVXs&pp=ygUR7IOd7Zmc7L2U65SpICBqd3Q%3D
์ฐธ๊ณ ํ๋ฉด ๋์์ด ๋ง์ด ๋ ๊ฑฐ ๊ฐ๋ค.
์์ ์์ฑํ ๋ด์ฉ์์ jwtํ ํฐ์ header์ payload, ๊ทธ๋ฆฌ๊ณ header์ payload๋ฅผ SecretKey๋ก ์ํธํํ์ฌ 3๊ฐ์ง์ base64๋ฅผ "."์ผ๋ก ์ด์ด์ ๋ง๋ ๋ค๊ณ ํ๋ค.
์ฌ๊ธฐ์ SecretKey๋ ์๋ฒ๋ง์ด ์๊ณ ์๋ค(์๊ณ ์์ด์ผ๋งํ๋ค.)
๋ฐ๋ผ์ ๊ฒ์ฆ๋ฐฉ๋ฒ์ ์๋ฒ๋ ํด๋ผ์ด์ธํธ๊ฐ token์ ๋ณด๋ด๋ฉด ํด๋น ํ ํฐ์ header์ payload๋ฅผ ๊ฐ์ ธ์์ ๋์ฝ๋ฉํ ๋ค์,
์๋ฒ์ ๋ฑ๋ก๋ SecretKey๋ก ๋ค์ ํ ๋ฒ ํ ํฐ์ ๋ง๋ ๋ค.
์ด๋ ์๋ฒ์์ ๊ฒ์ฆ์ ์ํด ๋ค์ ๋ง๋ ํ ํฐ๊ณผ ํด๋ผ์ด์ธํธ์์ ์ ์ก๋ ํ ํฐ์ ๋น๊ตํ์ฌ ๊ฒ์ฆํ๋ ๋ฐฉ์์ด๋ผ๊ณ ํ๋ค.
๐ซ ํ ํฐ ๋ฐ๊ธ
์ฐ์ ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ฅผ ์ฐ๊ฒฐํ์ฌ ๊ฐ๋จํ ๋ก๊ทธ์ธ ๋ก์ง Client Server๋ฅผ ๋ง๋ค์.( ๐ ํฅํ MongoDB ์นดํ
๊ณ ๋ฆฌ ์์ฑ ํ ๋งํฌ ์ฐ๊ฒฐํ๊ธฐ )
๐ ์ฟ ํค ๊ด๋ฆฌ ์ฝ๋ ์์ฑ
์ฐ์ ์ฟ ํค๋ฅผ ๊ด๋ฆฌํ๊ธฐ ์ํด ์ฟ ํค ๊ด๋ จ ๋ฉ์๋๋ฅผ ์ ์ํ๋ค.
import { Cookies } from 'react-cookie';
// ๋ฆฌ์กํธ ์ฟ ํค ์ธ์คํด์ค ์์ฑ
const cookies = new Cookies();
// ํด๋ผ์ด์ธํธ์ ์ฟ ํค๋ฅผ ์ ์ฅํฉ๋๋ค.
export const setCookie = (name, value, option) => {
return cookies.set(name, value, { ...option });
};
// ํด๋ผ์ด์ธํธ์ ์ฟ ํค๋ฅผ ๊ฐ์ ธ์ต๋๋ค.
export const getCookie = (name) => {
return cookies.get(name);
};
// ํด๋ผ์ด์ธํธ์ ์ฟ ํค๋ฅผ ์ญ์ ํฉ๋๋ค.
export const removeCookie = (name) => {
return cookies.remove(name);
};
๐ ๋ก๊ทธ์ธ ์ฝ๋ ์์ฑ
๋ก๊ทธ์ธ ๊ณผ์ ์ ๋ค์๊ณผ ๊ฐ๋ค.
const executeLogin = async (e) => {
e.preventDefault();
if (input.userId && input.userPw) {
// 1. ์ฌ์ฉ์๊ฐ ์
๋ ฅํ ์์ด๋์ ํจ์ค์๋๋ฅผ ๋ฐ์
const payload = {
id: input.userId,
password: input.userPw,
};
// 2. login์ ๊ด๋ฆฌํ๋ ์๋ฒ๋ก api๋ฅผ post ์์ฒญ์ ๋ณด๋ธ๋ค.
const response = await axios.post('/auth/login', payload, {
headers: {
'Content-Type': `application/json`,
'Access-Control-Allow-Origin': `*`,
'Access-Control-Allow-Credentials': 'true',
Authorization: `Bearer ${getCookie('accesss_token')}`,
},
});
if (response?.data.success) {
// 3. Server์ ์๋ต์ผ๋ก๋ถํฐ ๋ฐ๊ธ๋ ํ ํฐ์ ์ฟ ํค์ ์ ์ฅ ํ ๊บผ๋ด์ด ์ฌ์ฉ
// httpOnly
setCookie('access_token', `${response.data.access_token}`);
// 4. ๋ฐ๊ธ ๋ฐ์ ํ ํฐ์ API ํต์ ํ ๋, headers ๊ธฐ๋ณธ๊ฐ์ ๋ด์์ ์ฌ์ฉ
axios.defaults.headers.common[
'Authorization'
] = `Bearer ${response.data.access_token}`;
navigate('/', { replace: true });
} else {
alert(response.data.message);
}
} else {
alert('ํ์ ์ ๋ณด๋ฅผ ์
๋ ฅํด์ฃผ์ธ์.');
}
};
์ด๋ฌ๋ฉด ํด๋ผ์ด์ธํธ ๋ธ๋ผ์ฐ์ ์ ์ฟ ํค๋ฅผ ์ ์ฅํ ์ ์๋ค.
โ ๏ธ ๋ณด์ ์ทจ์ฝ
๋ค์๊ณผ ๊ฐ์ด ์์ฑํ๋ฉด ์ํธํ ์งํ ํ ํ ํฐ์ผ๋ก ๋ฐ๊ธ๋์ด ์ ์ฅ์ด ๋์ง๋ง, ํ ํฐ ๋ฐฉ์์ ํด๋น ํ ํฐ ๊ฐ์ ๋ณด์ฌ์ฃผ๋๊ฒ ๊ฒ์ฆํ๋๊ฒ ๋ค ์ด๊ธฐ ๋๋ฌธ์ ๋๊ตฐ๊ฐ์๊ฒ ํ์ทจ ๋นํ๋ฉด ์ ํจ์๊ฐ๊น์ง ํด์ปค์๊ฒ ๋นํ ์ ๋ฐ์ ์๋ค.
ํด์ปค๊ฐ ์ฌ์ฉ์์๊ฒ javascript ๋ฌธ๋ฒ์ ์ ์กํ๋ค๋ฉด ํ์ทจ ๋นํ ์ ์๋ค.
๊ฐ๋ฐ์ ๋๊ตฌ๋ฅผ ์ด๊ณ document.cookie๋ฅผ ๊ฒ์ํ๋ฉด ํ์ฌ ๋ํ๋จผํธ์ ์กด์ฌํ๋ ์ฟ ํค๋ฅผ ํ์ธํ ์ ์๋ค.
์ด๋ฌํ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํด javascript๋ก์ ์ ๊ทผ์ ๊ธ์งํ์ฌ์ผํ๋๋ฐ ๋ฐฉ๋ฒ์ ๋ค์๊ณผ ๊ฐ๋ค.
(์ด๋ป๊ฒ ๊ฐ๋ฐํด์ผ ์ต์ ์ ๋ณด์์ ์ ์งํ ์ง ๊ณต๋ถํ๊ณ ์ฌ์์ฑ ํ๊ฒ ์ต๋๋ค.)
'Library > jwt' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[ jwt ] AccessToken๊ณผ RefreshToken (0) | 2024.02.23 |
---|---|
[ jwt ] jwt์ ๊ตฌ์กฐ (0) | 2024.02.23 |
[ jwt ] ๋ก๊ทธ์ธ - Json Web Token์ ๋ํด ์์๋ณด๊ธฐ (0) | 2024.02.21 |