TIL - Komma 프로젝트(6) - 회원가입 , 로그인 구현

0
post-thumbnail

첫번째로 작업한 controller는 회원가입과 로그인 이다.

1. 회원가입

회원가입을 할때는 클라이언트에서 username과 eamil, password를 보내준다.

import { Request, Response } from "express";
import { getConnection } from "typeorm";
import { getManager } from "typeorm";
import User from "../../entity/User";
import crypto from "crypto";
export default async (req: Request, res: Response) => {
  const email = req.body.email;
  const password = req.body.password;
  const username = req.body.username;
  if (!email || !password || !username) {
    res.status(422).send({ message: "insufficient parameters supplied" });
  }
  const isemail = await getManager()
    .createQueryBuilder(User, "User")
    .where({ email: email })
    .getOne();

  if (isemail) {
    res.status(409).send({ message: "email exists" });
  } else {
    const createSalt: Function = () =>
      new Promise((resolve, reject) => {
        crypto.randomBytes(64, (err, buf) => {
          if (err) reject(err);
          resolve(buf.toString("base64"));
        });
      });
    const createHashedPassword: Function = (plainpassword) =>
      new Promise(async (resolve, reject) => {
        const salt = await createSalt();
        crypto.pbkdf2(plainpassword, salt, 1000, 64, "sha512", (err, key) => {
          if (err) reject(err);
          resolve({ hashPwd: key.toString("base64"), salt });
        });
      });
    const { hashPwd, salt } = await createHashedPassword(password);
    await getConnection()
      .createQueryBuilder()
      .insert()
      .into(User)
      .values({
        email: email,
        password: hashPwd,
        username: username,
        darkMode : false,
        siteColor : "random",
        salt: salt,
      })
      .execute();
    res.status(201).send({ message: "Sign successfully" });
  }
};

요구하는 3가지 값이 들어오면 먼저 password를 암호화 하는 작업을 한다. slat를 생성하고 생성한 salt와 hash 함수를 이용 하여 암호화를 하고 디비에 저장한다.

사이트 옵션인 darkMode와 siteColr는 디폴트 값으로 저장하고 , username과 email, password는 클라에서 보내준 값으로 저장한다.

디비에 저장 할때는 typeorm을 사용하였다.

2. 로그인

import { Request, Response } from "express";
import { getManager } from "typeorm";
import User from "../../entity/User";
import crypto from "crypto";
import "dotenv/config";
import jwt from 'jsonwebtoken'

export default async (req: Request, res: Response) => {
  const email: string = req.body.email;
  const password: string = req.body.password;
  const user = await getManager()
    .createQueryBuilder(User, "User")
    .where({ email: email })
    .getOne();
  
  if (!user) {
    res.status(400).send({ data: null, message: "not authorized" })
  } else {
    const { salt } = user;
    const createHashedPassword = (plainpassword: string) =>
      new Promise(async (resolve, reject) => {
        crypto.pbkdf2(plainpassword, salt, 1000, 64, 'sha512', (err, key) => {
          if (err) reject(res.status(400).send({ message: "hashPwd exists" }));
          resolve(key.toString('base64'));
        });
      });
    const hashPwd = await createHashedPassword(password);

    const userInfo = await getManager()
      .createQueryBuilder(User, "User")
      .where({ password: hashPwd })
      .getOne()

    const accessToken = jwt.sign(
      {
        'id': userInfo.id,
        'username': userInfo.username,
        'email': userInfo.email,
        'darkMode': false,
        'siteColor': "random",
      },
      process.env.ACCESS_SECRET,
      { expiresIn: '1d' });//하루 뒤 파괴
    res.send({ accessToken: accessToken, message: "Login successfully" })
  }

};

로그인 할때는 클라에서 보내준 email과 password를 이용한다. 먼저 동일한 이메일이 있는지 확인 하고 이메일이 있으면 그 유저의 salt로 비번을 해쉬함수를 이용하여 암호화를 하고 일치하는 비번이 있는지 찾고 있으면, 토큰을 발급해준다.

profile
👩🏻‍💻항상발전하자 🔥

0개의 댓글