[항해99] 26일차 , 27일차 주특기 심화시작

IT/Bootcamp 항해99|2021. 7. 5. 11:17

 


항해 99

 

 

26 & 27 일차 :  

주특기 심화 , Node JS 심화주가 시작되었다.

 

1주차에서는 기본  CRUD개념을 복습했다.

저번주에 만든  API를 보고  한번 복습하니깐   API만드는게 좀 익숙해진것같다.

 

 

 

 

JWT기본지식:

더보기

JWT -  로그인 기능 을 위한 기술인데 변조가 불가능하여 요즘 많이 쓰인다.

 

1.변조가 불가능하다

2. 하지만 열람은 아무나 가능하다.

 

그렇기 때문에 중요한 정보는 넣어서 보내지말자.  노출해도 되는 정보들만 ( user ID 등 ) 만 보내자.

 

쉽게: 

토큰을 확인해보고 -> 토큰이  정상이면  -> 유저가 원하는 페이지를 보여준다.

로그인했으면 -> 토큰이있다

 

 

https://jwt.io/

 

로그인 화면  추가 (Sign inAPI)

회원가입 추가 (Sign up API)

 

 

항상 sing in API -(  GET/users/me) 을 호출하여 토큰을 가지고있는지 확인한다.

만약 토큰이 잘못되었으면 다시 로그인 페이지 호출

토큰이 있으면 -> 유저가 원하는 페이지를 보여줌 

토큰이 없으면 -> 로그인 페이지 보여주기

목록페이지에서  로그인 페이지로 옮길때 토큰을 지워준다.

 

 

 

 

 

로그인 및 auth 부분 구현 

더보기

 

API만들때 생각해보니깐 일반 유저가 api를 쓰진않을것같다. 그래서 사람들이 모두 router에 /api/ 지정해주고 그다음 주소를 만드는것같다.

 

 

 1)  회원가입 

 강의에서  ajax통신에서 nickname, email,password,confirmpassword를 가져온다

$.ajax({
          type: "POST",
          url: "/api/users",
          data: {
            nickname: nickname,
            email: email,
            password: password1,
            confirmPassword: password2,
          },
          success: function (response) {
            customAlert("회원가입을 축하드립니다!", function () {
              window.location.replace("/");
            });
          },
          error: function (error) {
            customAlert(error.responseJSON.errorMessage);
          },
        });

그러면  api에서 회원가입은 생성하는거니깐

post로한다. get으로할수도있지만  get은 body에 넣어서 데이터를 보내지않고 url? 이렇게 보내니깐 보안에안좋으니깐 post로쓴다.

 

ajax에서 받아온 nickname, email,passowrd,confirmpassword를 받고나서,

 

맨첫번쨰로 passwrod !== confrimpasword를 확인한다.

틀리면 바로 error message반환

 

맞으면, User를 user Schema로 해서 새로만들어주고 저장.

 

router.post("/users", async (req, res) => {
  const { nickname, email, password, confirmPassword } = req.body;

  if (password !== confirmPassword) {
    res.status(400).send({ errorMessage: " Password not match" });
    return;
  }

  const existsUsers = await User.find({
    $or: [{ email }, { nickname }],
  });
  if (existsUsers.length) {
    res.status(400).send({
      errorMessage: " You already have same nickname or email  ed",
    });
    return;
  }

  const user = new User({ email, nickname, password });
  await user.save();
  res.status(201).send({});
});

 

 

2) 로그인 기능 

 

 

로그인 ajax

 

로그인은  email과 password를 보내준다.

function sign_in() {
        let email = $("#inputEmail").val();
        let password = $("#inputPassword").val();
        $.ajax({
          type: "POST",
          url: "/api/auth",
          data: {
            email: email,
            password: password,
          },
          success: function (response) {
            localStorage.setItem("token", response.token);
            window.location.replace("/goods.html");
          },
          error: function (error) {
            customAlert(error.responseJSON.errorMessage);
          },
        });
      }

 

 

 

로그인 API

 

첫번째로, req.body에서받아서 그값들을 db에서 찾아본다.  

 

findOne대신 find를써도된다.     

 

만약User가 존재하지않으면 에러

존재한다면,  jwt  userId를 토큰으로 반환해준다.

 

token을받아주면 ajax에서 setItem으로 localstorage에 넣어준다?  -> 이부분은 공부가 더필요한것같다 이해안댐

 

router.post("/auth", async (req, res) => {
  const { email, password } = req.body;

  const user = await User.findOne({ email, password }).exec();

  if (!user) {
    res.status(401).send({ errorMessage: "email or password is not match" });
    return;
  }

  const token = jwt.sign({ userId: user.userId }, "this_is_my_secret");
  res.send({
    token,
  });
});

 3) 인증 미들웨어

HTTP 인증할때 header 를사용해서 규격이나와있다.

header에다가 authorization + token내용:

Authorization: Bearer JWT토큰내용

 

 

https://developer.mozilla.org/ko/docs/Web/HTTP/Authentication

 

HTTP 인증 - HTTP | MDN

HTTP는 액세스 제어와 인증을 위한 프레임워크를 제공합니다. 가장 일반적인 인증 방식은 "Basic" 인증 방식입니다. 이 페이지에서는 일반적인 HTTP 인증 프레임워크를 소개하고 서버에 HTTP의 Basic

developer.mozilla.org

middlewears/auth-middleware.js

  middleware basic frmae:

module.exports=(req,res,next)=>{
	next();  // must be here for the middleware so it will pass to next 
 }

 

header에서 auhtorization을받아온다.

 받은  authorization을  tokenType과 tokenValue로 나눠야해.

authorization에 Bearer이면, verfy 해야지. verify할때 key는 token만들때 key ("this_is_my_secret") 이랑 같아야해

 verified된 id로 다시 db에서 찾아서  그값을 

res.locals.user =user에다가 넣어서 보내준다

 

 

const jwt = require("jsonwebtoken");
const User = require("../models/user");

// header  :  Authorization :
module.exports = (req, res, next) => {
  const { authorization } = req.headers;
  const [tokenType, tokenValue] = authorization.split(" ");
  console.log(tokenValue);

  if (tokenType !== "Bearer") {
    res.status(401).send({ errorMessage: "Login please " });
    return;
  }

  try {
    const { userId } = jwt.verify(tokenValue, "this_is_my_secret");

    User.findById(userId)
      .exec()
      .then((user) => {
        res.locals.user = user;
        next(); // middleweare must have
      });
  } catch (error) {
    res.status(401).send({ errorMessage: "Login please " });
    return;
  }
};

 

4) 내정보조회 

 

function getSelf(callback) {
  $.ajax({
    type: "GET",
    url: "/api/users/me",
    headers: {
      authorization: `Bearer ${localStorage.getItem("token")}`,
    },
    success: function (response) {
      callback(response.user);
    },
    error: function (xhr, status, error) {
      if (status == 401) {
        alert("로그인이 필요합니다.");
      } else {
        localStorage.clear();
        alert("알 수 없는 문제가 발생했습니다. 관리자에게 문의하세요.");
      }
      window.location.href = "/";
    },
  });
}

 

API

 

res.local에 넣어놓은 user  값을 가지고와서  email과 nickname을 가져오지. 

router.get("/users/me", authMiddleware, async (req, res) => {
  const { user } = res.locals;
  console.log(user);
  res.send({
    user: {
      email: user.email,
      nickname: user.nickname,
    },
  });
});

 

 

 

어떤 20년차 개발자님의 블로그

JS기본 개념에대해 읽어보기좋은것같다.

 

https://poiemaweb.com/coding

 

Progmamming | PoiemaWeb

프로그래밍은 수행되어져야 하는 명령을 컴퓨터에 전달하는 일종의 커뮤니케이션이다. 이때

poiemaweb.com

 

반응형

댓글()