Skip to content

Commit

Permalink
πŸŽ‰ add : νšŒμ›κ°€μž… & 둜그인 API μΆ”κ°€
Browse files Browse the repository at this point in the history
  • Loading branch information
hyeonseol00 committed Jun 17, 2024
1 parent a5c71f3 commit 5b227ed
Show file tree
Hide file tree
Showing 3 changed files with 112 additions and 0 deletions.
38 changes: 38 additions & 0 deletions src/middlewares/auth.middleware.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import jwt from 'jsonwebtoken';

export default async function (req, res, next) {
try {
const { authorization } = req.cookies;
if (!authorization) throw new Error('토큰이 μ‘΄μž¬ν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€.');

const [tokenType, token] = authorization.split(' ');
if (tokenType !== 'Bearer')
throw new Error('토큰 νƒ€μž…μ΄ μΌμΉ˜ν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€.');

const decodedToken = jwt.verify(token, process.env.TOKEN_SECRET_KEY);
const id = decodedToken.id;
const account = getAccounts().find((account) => account.id == loginId);

if (!account) {
res.clearCookie('authorization');
throw new Error('토큰 μ‚¬μš©μžκ°€ μ‘΄μž¬ν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€.');
}

req.account = account;

next();
} catch (error) {
res.clearCookie('authorization');

switch (error.name) {
case 'TokenExpiredError':
return res.status(401).json({ message: '토큰이 λ§Œλ£Œλ˜μ—ˆμŠ΅λ‹ˆλ‹€.' });
case 'JsonWebTokenError':
return res.status(401).json({ message: '토큰이 μ‘°μž‘λ˜μ—ˆμŠ΅λ‹ˆλ‹€.' });
default:
return res
.status(401)
.json({ message: error.message ?? '비정상적인 μš”μ²­μž…λ‹ˆλ‹€.' });
}
}
}
9 changes: 9 additions & 0 deletions src/models/account.model.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
const accounts = [];

export const addAccount = (account) => {
accounts.push(account);
};

export const getAccounts = () => {
return accounts;
};
65 changes: 65 additions & 0 deletions src/routes/accounts.router.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
import express from 'express';
import bcrypt from 'bcrypt';
import jwt from 'jsonwebtoken';
import { addAccount, getAccounts } from '../models/account.model.js';

const router = express.Router();
const regex = /^[A-Za-z0-9]*$/;

/** μ‚¬μš©μž νšŒμ›κ°€μž… API **/
router.post('/sign-up', async (req, res, next) => {
try {
const { loginId, password } = req.body;
const isExistUser = getAccounts().find((account) => account.id == loginId);
console.log(getAccounts());

if (isExistUser)
return res.status(409).json({ message: '이미 μ‘΄μž¬ν•˜λŠ” IDμž…λ‹ˆλ‹€.' });
else if (!regex.test(loginId))
return res
.status(400)
.json({ message: 'IDλŠ” μ˜μ–΄μ™€ 숫자만 μ‚¬μš©ν•  수 μžˆμŠ΅λ‹ˆλ‹€.' });
else if (password.length < 6)
return res
.status(400)
.json({ message: 'λΉ„λ°€λ²ˆν˜ΈλŠ” 6자 이상이어야 ν•©λ‹ˆλ‹€.' });

const hashedPassword = await bcrypt.hash(password, 10);

// DB μ €μž₯λΆ€
addAccount({ id: loginId, password: hashedPassword });

return res.status(201).json({ message: 'νšŒμ›κ°€μž…μ΄ μ™„λ£Œλ˜μ—ˆμŠ΅λ‹ˆλ‹€.' });
} catch (error) {
next(error);
}
});

/** μ‚¬μš©μž 둜그인 API **/
router.post('/sign-in', async (req, res, next) => {
try {
const { loginId, password } = req.body;
// DB ν˜ΈμΆœλΆ€
const account = getAccounts().find((account) => account.id == loginId);

if (!account)
return res.status(401).json({ message: 'μ‘΄μž¬ν•˜μ§€ μ•ŠλŠ” IDμž…λ‹ˆλ‹€.' });
else if (!(await bcrypt.compare(password, account.password)))
return res.status(401).json({ message: 'λΉ„λ°€λ²ˆν˜Έκ°€ μΌμΉ˜ν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€.' });

const token = jwt.sign(
{
id: account.id,
},
process.env.TOKEN_SECRET_KEY,
);

res.cookie('authorization', `Bearer ${token}`);

return res.status(200).json({ message: '둜그인 성곡' });
} catch (error) {
next(error);
}
});

export default router;

0 comments on commit 5b227ed

Please sign in to comment.