Login #01

join은 끝났다.

어떻게 계정을 만드는지 해봤고 에러를 처리하고 상태 코드는 어떻게 보내는지도 해봤다.

계정을 성공적으로 생성했으면 로그인을 해야한다.

원한다면 이 부분을

userController.js에서

 const exists = await User.exists({ $or: [{ username }, { email }] });
  if (exists) {
    return res.status(400).render("join", {
      pageTitle,
      errorMessage: "This username/email is already taken.",
    });
  }
  try {
    await User.create({
      name,
      username,
      email,
      password,
      location,
    });
    return res.redirect("/login");
  } catch (error) {
    return res.status(400).render("join", {
      pageTitle: "join",
      errorMessage: error._message,
    });
  }
};

try ~ catch 구문 안에 넣었다. videoController.js에서 했던 것처럼 만들었다.

거의 똑같이 해주었다. 처리하지 못한 에러가 있을수도 있으니까 지금 최대한 많은 에러를

처리를 하고 있다. 이미 사용중인 usernamepassword가 일치 하는지 확인하고 있다.

그래도 다른 에럭가 있을 수도 있다. videoController에서 했던 것처럼 try~catch를 사용해서

에러를 방지 할수 있다. DB에러가 발생 했을때 upload가 아니라 joinrender하면 된다.

더 안전해 지는 거다. User를 만들때도 try~catch를 쓰고 있는거다.

그런데 이건 직접 에러를 처리하고 난 다음에 쓰는 거다.

if (password !== password2) {
    return res.status(400).render("join", {
      pageTitle,
      errorMessage: "Password confirmation does not match.",
    });
  }
  const exists = await User.exists({ $or: [{ username }, { email }] });
  if (exists) {
    return res.status(400).render("join", {
      pageTitle,
      errorMessage: "This username/email is already taken.",
    });
  }

이제 로그인 페이지를 만들어 보도록 한다.

먼저 join파일에서 시작해 보도록 한다.

join.pug에서

hr
div 
	span Already have an account?
  	a(href="/login") Log in now →

새로고침 하면 하단에 "이미 계정이 있습니까? 로그인 하세요 ->" 까지 잘 나온다.

이제 login을 클릭하면 /login으로 넘어가게 된다. 아직은 텍스트만 나온다.

userController.js에서

export const getLogin = (req, res) => res.send("Login");
export const edit = (req, res) => res.send("Edit User");
export const remove = (req, res) => res.send("Remove User");
export const logout = (req, res) => res.send("Log out");
export const see = (req, res) => res.send("See User");

순서를 바꿔 주고 router를 만들 필요는 없다. 이미 router가 있으니까

routers폴더에서 rootRouter로 이동하면

import { getJoin, postJoin, getLogin } from "../controllers/userController";
rootRouter.route("/login").get(getLogin);

get("/login")login function을 호출한다.

이제 여기서 getpost를 써야 된다는걸 알고 있다.

그래서 import 부분의 logingetLogin으로 바꿔 주고

rootRouter 부분도 바꿔 준다. get이 아니라 route로 변경해준다.

rootRouter.route("/login").get(getLogin);

userController.js에서도 getLogin으로 변경해준다.

이제 새로고침을 했을때 아무것도 바뀌는게 있으면 안된다. 다행히 바뀐게 없다.

지금 controller의 이름만 바꿔 주었다. route구조로 바꾸기도 했는데 내용은 바꾸지 않았다.

이제 login templaterender한다.

userControllergetLogin에서

export const getLogin = (req, res) => res.render("login");

res.send()res.render()로 바꿔 주었다. Loing은 소문자로 변경한다.

이제 login이라는 이름을 가진 파일을 만들어야 한다.

views폴더로 가서 login.pug파일을 만든다. login templatejoin이랑 엄청 비슷한거다.

그래서 모두 복붙해준다.

extends base


block content 
    if errorMessage
        span=errorMessage
    form(method="POST")
        input(placeholder="Username",name="username", type="text", requeired)
        input(placeholder="Password",name="password", type="password", requeired)
        input(type="submit", value="Join")
    hr
    div 
        span Don't have an account?   
        a(href="/login") Create one now →

login template에 붙여 넣고 내용을 바꿔준다.

그리고 로그인 할때는 nameemail을 입력하지 않아도 된다.

그저 usernamepassword만 있으면 된다. 나머지는 삭제해 준다.

전에 했던거랑 크게 다를게 없다. HTML을 코드를 지워서 template만 수정 했을 뿐이다.

새로고침을 해주면 usernamepassword 입력하는 칸만 남았다.

Create one now를 누르면 /join으로 가게 만들어 준다.

        a(href="/join") Create one now →

아직 template에는 pageTitle이 없다.

pageTitle을 만들어 준다.

userControoller로 가서 pageTitle을 써주면 된다.

export const getLogin = (req, res) =>
  res.render("login", { pageTitle: "Login" });

새로고침하면 잘 작동한다. 그리고 join버튼도 거슬리니 Login버튼으로 바꿔 준다.

login.pug에서

input(type="submit", value="Login")

이제 /login으로 post요청을 받았을때 어떻게 하면 될까??

우선 입력한 username을 가진 User가 존재하는지 확인해야한다.

해당 계정이 존재하지 않을수도 있다. 그리고 password를 확인하면 된다.

우선 post controller를 만들어 본다.

export const getLogin = (req, res) =>
  res.render("login", { pageTitle: "Login" });

export const postLogin = (req, res) => {
  // check if account exists
  //  check if password correct
  res.end();
};

일단 res.end()만 써준다. 그리고 주석처리를 해서 '계정이 존재하는지 체크',

'패스워드가 일치하는지 체크 ' 이렇게 적어 줬다.

이제 이 postlogin controllerrouter에서 사용하도록 한다.

import {
  getJoin,
  postJoin,
  getLogin,
  postLogin,
} from "../controllers/userController";
rootRouter.route("/login").get(getLogin).post(postLogin);

/login으로 post요청을 보내면 postLogin을 호출하게 만든다. import도 해준다.

이제 route("/join"),getJoin... route("/login"),getLogin,postLogin

이 생겼다. 어느 정도 구조가 생긴게 보인다.

이제 post요청을 보내면 body에서 usernamepassword를 받게 된다.

그러면 body에서 usernamepassword를 꺼내보도록 한다.

userController.js에서

export const postLogin = (req, res) => {
  const { username, password } = req.body;
  // check if account exists
  //  check if password correct
  res.end();
};

다음으로 mongoose를 사용할 차례이다.

그래서 async,await를 써서

export const postLogin = async (req, res) => {
  const { username, password } = req.body;
  const exists = await User.exists({ username });
  if (!exists) {
    return res
      .status(400)
      .render("login", {
        pageTitle: "Login",
        errorMessage: "An account with this username does not exists.",
      });
  }

받은 username과 일치하는 User가 있는지 확인해 본다.

const exists를 만들고 mongoose에서 가져온 await User를 쓴다.

User.exists() 그리고 username이 받은 username과 같은 User를 찾을거다.

그리고 에러를 체크한다. 만약 존재하지 않는다면 res.status(400)return하고

Bad Request인 400을 보내고 login formrender한다.

pageTitle도 추가한다. 그리고 errorMessage도 써줬다.

"입력한 username을 가진 User가 존재하지 않습니다."

이제 에러가 발생하는지 테스트해 본다. 에러메세지가 잘 작동한다.

이번에는 존재하는 username을 입력해 본다. 아무것도 나오지 않는다.

왜냐하면 res.end()만 썼으니까 그렇다.

좋은 웹페이지 즐겨찾기