Syw.Frontend

๐Ÿงฉ Vue 2๋กœ ๋ฐฐ์šฐ๋Š” ํ”„๋ก ํŠธ์—”๋“œ ๊ธฐ์ดˆ

1๋‹จ๊ณ„. Vue 2 + Express + Axios ์ธ์ฆ ๊ธฐ๋ฐ˜ ํˆฌ๋‘์•ฑ ๋งŒ๋“ค๊ธฐ

1-14. ์ปค์Šคํ…€ ๋กœ๊ทธ์ธ ๊ตฌํ˜„ โ€“ JWT ๊ธฐ๋ฐ˜ ์ธ์ฆ

์‚ฌ์šฉ์ž ํšŒ์›๊ฐ€์ž…๊ณผ ๋กœ๊ทธ์ธ, ๊ทธ๋ฆฌ๊ณ  JWT ๋ฐœ๊ธ‰์„ ์ฒ˜๋ฆฌํ•ฉ๋‹ˆ๋‹ค.

โœ… ์•„๋ž˜์ฒ˜๋Ÿผ server.js๋ฅผ ๊ตฌ์„ฑํ•ด๋ณด์„ธ์š”:

const express = require('express');
const cors = require('cors');
const todosRouter = require('./routes/todos');
const authRouter = require('./routes/auth');
const app = express();
const PORT = 3000;

app.use(cors());
app.use(express.json());

// โœ… RESTful router ๋“ฑ๋ก
app.use('/todos', todosRouter);
app.use('/auth', authRouter); // /auth/register, /auth/login

app.listen(PORT, () => {
  console.log(`๐Ÿš€ ์„œ๋ฒ„ ์‹คํ–‰ ์ค‘: http://localhost:${PORT}`);
});

โœ… ๊ทธ๋ฆฌ๊ณ  routes/auth.js ๋ผ์šฐํ„ฐ ํŒŒ์ผ์„ ์ƒ์„ฑํ•˜์„ธ์š”:

routes/auth.js

jwt ํ† ํฐ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์„ค์น˜ํ•ฉ๋‹ˆ๋‹ค.

npm i jsonwebtoken

โœ… routes/auth.js

const express = require('express');
const fs = require('fs');
const path = require('path');
const jwt = require('jsonwebtoken');

const router = express.Router();
const USERS_FILE = path.join(__dirname, '../data/users.json');
const SECRET = 'my-vue-jwt-secret'; // JWT ์„œ๋ช…์šฉ ๋น„๋ฐ€ ํ‚ค

// ์œ ์ € ๋ชฉ๋ก ๋ถˆ๋Ÿฌ์˜ค๊ธฐ
function getUsers() {
  if (!fs.existsSync(USERS_FILE)) return [];
  const data = fs.readFileSync(USERS_FILE, 'utf-8');
  return JSON.parse(data);
}

// ๐Ÿ” ํšŒ์›๊ฐ€์ž…
router.post('/register', (req, res) => {
  const { username, password } = req.body;
  const users = getUsers();

  const exists = users.find(u => u.username === username);
  if (exists) {
    return res.status(400).json({ message: '์ด๋ฏธ ์กด์žฌํ•˜๋Š” ์•„์ด๋””์ž…๋‹ˆ๋‹ค.' });
  }

  users.push({ username, password });
  fs.writeFileSync(USERS_FILE, JSON.stringify(users, null, 2));
  res.status(201).json({ message: 'ํšŒ์›๊ฐ€์ž… ์™„๋ฃŒ' });
});

// ๐Ÿ” ๋กœ๊ทธ์ธ + JWT ๋ฐœ๊ธ‰
router.post('/login', (req, res) => {
  const { username, password } = req.body;
  const users = getUsers();

  const found = users.find(u => u.username === username && u.password === password);
  if (!found) {
    return res.status(401).json({ message: '์•„์ด๋”” ๋˜๋Š” ๋น„๋ฐ€๋ฒˆํ˜ธ๊ฐ€ ์˜ฌ๋ฐ”๋ฅด์ง€ ์•Š์Šต๋‹ˆ๋‹ค.' });
  }

  const token = jwt.sign({ username }, SECRET, { expiresIn: '1h' });
  res.json({ token, username });
});

module.exports = router;

โœ… ๊ฐ™์ด ์ค€๋น„ํ•ด์•ผ ํ•  ํŒŒ์ผ

  • data/users.json (์ดˆ๊ธฐ์—๋Š” ๋นˆ ๋ฐฐ์—ด):
[]

Postman์œผ๋กœ ์ปค์Šคํ…€ ๋กœ๊ทธ์ธ API ํ…Œ์ŠคํŠธํ•˜๊ธฐ

์ด๋ฒˆ ๊ฐ•์ขŒ์—์„œ๋Š” Postman์„ ํ™œ์šฉํ•ด ์šฐ๋ฆฌ๊ฐ€ ๋งŒ๋“  ํšŒ์›๊ฐ€์ž…๊ณผ ๋กœ๊ทธ์ธ API๋ฅผ ์ง์ ‘ ํ˜ธ์ถœํ•˜๊ณ , JWT๊ฐ€ ๋ฐœ๊ธ‰๋˜๋Š” ๊ณผ์ •์„ ํ™•์ธํ•ด๋ด…๋‹ˆ๋‹ค.


๐Ÿ”ง 1๋‹จ๊ณ„: Postman ์„ค์น˜ ๋ฐ ์‹คํ–‰

  • Postman ๊ณต์‹ ์‚ฌ์ดํŠธ:

    ๐Ÿ‘‰ https://www.postman.com/downloads

  • ์„ค์น˜ ํ›„ ์‹คํ–‰ํ•˜๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์ธํ„ฐํŽ˜์ด์Šค๊ฐ€ ๋œน๋‹ˆ๋‹ค.


๐Ÿงช 2๋‹จ๊ณ„: ํšŒ์›๊ฐ€์ž… API ํ…Œ์ŠคํŠธ

โžค ์ƒˆ ์š”์ฒญ ์ƒ์„ฑ

  • Method: POST
  • URL: http://localhost:3000/auth/register

โžค Body ์„ค์ •

  • ์ƒ๋‹จ ํƒญ์—์„œ Body โ†’ raw ์„ ํƒ
  • ์šฐ์ธก ๋“œ๋กญ๋‹ค์šด์—์„œ JSON ์„ ํƒ
  • ์•„๋ž˜ ๋‚ด์šฉ์„ ์ž…๋ ฅ:
{
  "username": "testuser",
  "password": "1234"
}

โžค ์ „์†ก (Send ๋ฒ„ํŠผ ํด๋ฆญ)

  • ์‘๋‹ต ์˜ˆ์‹œ:
{
  "message": "ํšŒ์›๊ฐ€์ž… ์™„๋ฃŒ"
}


๐Ÿงช 3๋‹จ๊ณ„: ๋กœ๊ทธ์ธ API ํ…Œ์ŠคํŠธ

โžค ์ƒˆ ์š”์ฒญ ์ƒ์„ฑ

  • Method: POST
  • URL: http://localhost:3000/auth/login

โžค Body ์„ค์ •

{
  "username": "testuser",
  "password": "1234"
}

โžค ์ „์†ก ๊ฒฐ๊ณผ

{
  "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6...",
  "username": "testuser"
}

์ด token์€ ์ดํ›„ ์š”์ฒญ ์‹œ ์ธ์ฆ์— ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค.


๐Ÿงฉ 4๋‹จ๊ณ„: JWT ํ™•์ธ ๋ฐ ์ €์žฅ ํ…Œ์ŠคํŠธ

  • ๋ฐ›์€ token์€ ๋กœ์ปฌ ์ €์žฅ์†Œ(localStorage) ๋˜๋Š” ์ฟ ํ‚ค์— ์ €์žฅํ•ด ์‚ฌ์šฉ์ž ์ธ์ฆ์— ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • ์ดํ›„ ์š”์ฒญ ์‹œ, ์•„๋ž˜์ฒ˜๋Ÿผ Authorization ํ—ค๋”์— ํฌํ•จํ•ฉ๋‹ˆ๋‹ค:
Authorization: Bearer <JWT ํ† ํฐ>

โœ… Tip: Postman Authorization ํƒญ ํ™œ์šฉ

  • Headers ์ˆ˜๋™ ์ž…๋ ฅ ์—†์ด๋„, Authorization ํƒญ ์„ ํƒ โ†’ Bearer Token ์˜ต์…˜ ์„ ํƒ
  • ๋ณต์‚ฌํ•œ JWT ํ† ํฐ์„ ๋ถ™์—ฌ๋„ฃ์œผ๋ฉด ํ—ค๋” ์ž๋™ ๊ตฌ์„ฑ๋จ

BE ์ €์žฅ์†Œ

GitHub - heroyooi/vue2-api at ch14

๐Ÿ’ฌ ๋Œ“๊ธ€

    โ€ป ๋กœ๊ทธ์ธ ํ›„ ๋Œ“๊ธ€์„ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.