Web/Node.js

2024-05-02

nomad06 2024. 5. 2. 08:57

Postman

 

 

Tweets

 

 

Auth 

 

폴더정리

 

폴더정리완료

 

 

// controller/auth.js

import * as authRepository from '../data/auth.js';
import bcrypt from 'bcrypt';
import jwt from 'jsonwebtoken';

/*
문제
jwt.js를 참고하여 controller/auth.js 에 토큰을 발행하고 login()에 로그인 완료되면 클라이언트에 토큰을 출력하는 프로세스를 만들어보자
*/

const secretKey = "abcd1234%^&*";
const jwtExpiresInDays = '2d';
const bcryptSaltRounds = 10;


// async function makeToken(id){
//     const token = jsonwebtoken.sign({
//         id: id,
//         isAdmin: false
//     }, secret, {expiresIn: '1h'})
//     return token;
// }

function createJwtToken(id){
    return jwt.sign({id}, secretKey, {expiresIn: jwtExpiresInDays});
}

/*
문제.
회원가입시 아이디 중복체크 하기
단. 중복이라면 409을 리턴
*/

// 회원가입
export async function signup(req, res, next){
    const {username, password, name, email, url} = req.body;
    const found = await authRepository.findByUsername(username);
    if(found){
        return res.status(409).json({message:`${username}이 이미 있습니다`});
    }
    const hashed = await bcrypt.hash(password, bcryptSaltRounds);
    const userId = await authRepository.createUser({username, hashed, name, email, url});
    const token = createJwtToken(userId);
    res.status(201).json({token, username});
}

/*
문제
controller/auth.js 에서 login()를 bcrypt를 적용하여 로그인 프로세스를 만들어보자
*/

//로그인
export async function login(req, res, next){
    const {username, password} = req.body;
    // const user = await authRepository.login(username);
    const user = await authRepository.findByUsername(username);
    if(!user){
        return res.status(401).json({message : '아이디를 찾을 수 없음'})
    }
    const isValidpassword = await bcrypt.compareSync(password, user.password);
    if(!isValidpassword){
        return res.status(401).json({message : `비밀번호가 틀렸음`});
    }
    const token = createJwtToken(user.id);
        return res.status(200).json({token, username});
}


export async function verify(req, res, next){
    const token = req.header['Token'];
    if(token){
        res.status(200).json(token);
    }
}

 

// data/auth.js

let users = [
    {
        id: '1',
        // userid: "apple",
        username: "apple",
        password: "$2b$10$TvIhNWYtvCNzOA0ZkmNg6.YU3EG49msPLzxphLYahMT63DVWRWZTe",
        name: "김사과",
        email: "apple@apple.com",
    },
    {
        id: '2',
        // userid: "banana",
        username: "banana",
        password: "$2b$10$TvIhNWYtvCNzOA0ZkmNg6.YU3EG49msPLzxphLYahMT63DVWRWZTe",
        name: "반하나",
        email: "banana@banana.com",
    }
]

// 아이디(username) 중복 검사
export async function findByUsername(username){
    return users.find((user) => user.username === username);
}

// id 중복 검사
export async function findById(id){
    return users.find((user) => user.id === id);
}

export async function createUser(user){
    const created = {id:'10', ...user }
    users.push(created);
    return created.id;
}

export async function login(username){
    return users.find((users) => users.username === username);
}

 

 

 

 

 

 

 

 

여기 토큰 아래 붙여넣기

 

Bearer 띄고 위 토큰 복붙

Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6IjEiLCJpYXQiOjE3MTQ2MjE1NDcsImV4cCI6MTcxNDc5NDM0N30.UHG0DmY_2hSfSG9K8Y4DAVQZJBGSWYtYB5yZi9D8zio

 

// middleware/auth.js

import jwt from 'jsonwebtoken';
import * as authRepository from '../data/auth.js';

const AUTH_ERROR = {message: "인증에러"};

export const isAuth = async(req, res, next) => {
    const authHeader = req.get('Authorization');
    console.log(authHeader);

    if(!(authHeader && authHeader.startsWith('Bearer'))) {
        console.log('에러1');
        return res.status(401).json(AUTH_ERROR);
    }
    const token = authHeader.split(' ')[1];

    jwt.verify(
        token, 'abcd1234%^&*',async(error, decoded) => {
            if(error) {
                console.log('에러2');
                return res.status(401).json(AUTH_ERROR);
            }
            const user = await authRepository.findById(decoded.id);
            if(!user){
                console.log('에러3');
                return res.status(401).json(AUTH_ERROR);
            }
            req.userId = user.id;
            next();
        }
    );
}

 

// tweets.js

import express from "express";
import * as tweetController from '../controller/tweet.js';
import { body } from 'express-validator';
import { validate } from "../middleware/validator.js";
import { isAuth } from "../middleware/auth.js";

const router = express.Router();

/*
    문제
    Post, Put에 text에 대해 빈문자열을 없애고, 최소 3자 이상 입력해야 데이터를 저장하도록 API에 적용
*/
const validateTweet = [
    body('text').trim().isLength({min: 3}).withMessage('최소 3자 이상 입력'), validate
]


// 해당 아이디에 대한 트윗 가져오기
// GET
// http://localhost:8080/tweets?username=:username
// http://localhost:8080/tweets?username=banana
router.get('/', isAuth, tweetController.getTweets);

// 글번호에 대한 트윗 가져오기
// GET
// http://localhost:8080/tweets/:id
// http://localhost:8080/tweets/1
router.get('/:id', isAuth, tweetController.getTweet);

// 트윗하기
// POST
// http://localhost:8080/tweets
// name, username, text
// json 형태로 입력 후 추가된 데이터까지 모두 json으로 출력
// {
//     "id":55,
//     "text":"트윗을 추가했어요555",
//     "name":"김사과",
//     "username":"apple"
// }
router.post('/', validateTweet, isAuth, tweetController.createTweet);

// 트윗 수정하기
// PUT
// http://localhost:8080/tweets/:id
// http://localhost:8080/tweets/1
// id, username, text
// json 형태로 입력 후 변경된 데이터까지 모두 json으로 출력
// {
//     "text":"트윗을 변경했어요!"
// }
router.put('/:id', validateTweet, isAuth, tweetController.createTweet);

// 트윗 삭제하기
// DELETE
// http://localhost:8080/tweets/:id:
router.delete('/:id', isAuth, tweetController.deleteTweet);

export default router;

 

// router/auth.js

import express from 'express';
import { body } from 'express-validator';
import * as authController from '../controller/auth.js';
import { validate } from '../middleware/validator.js';
import { isAuth } from '../middleware/auth.js';

const router = express.Router();

const validateLogin = [
    body('username').trim().notEmpty().withMessage('username을 입력하세요'),
    body('password').trim().isLength({min:4}).withMessage('password는 최소 4자 이상 입력하세요'), validate
];

const validateSignup = [
    ... validateLogin,
    body('name').trim().notEmpty().withMessage('name을 입력하세요'),
    body('email').isEmail().withMessage('이메일 형식을 확인하세요'),
    body('url').isURL().withMessage('URL 형식을 확인하세요'), validate
]


router.post('/signup', validateSignup, authController.signup);

router.post('/login', authController.login);

router.get('/me', isAuth, authController.me);

export default router;

'Web > Node.js' 카테고리의 다른 글

2024-05-07 관리자페이지팁,  (0) 2024.05.07
2024-05-03 환경 변수 관리, HTTP 통신, 웹소켓  (0) 2024.05.03
API 명세서  (0) 2024.04.30
2024-04-30  (0) 2024.04.30
2024-04-29 리팩토링  (0) 2024.04.29