Archive

npx vs npm 차이점

|

[펌] npx vs npm 차이점


npx란 무엇일까? 그리고 npm이랑 어떤 차이점이 있을까?

What are the differences between npm and npx ?

결론 :

  1. npx는 npm 5.2.0 버전부터 새롭게 추가된 도구로 따로 업데이트할 필요 없이 항상 최신 버전을 실행시킨다
  2. npm : Package Manager (관리), npx : Package Runner (실행기)
  3. npx는 패키지 설치 없이 실행할 수 있고, 아직 설치되지 않은 패키지가 있으면 자동으로 설치한다
  4. npm은 pacakge.json에 해당 패키지를 지정하고 로컬에 설치해야한다



참고 자료


npx란 무엇일까? 그리고 npm이랑 어떤 차이점이 있을까?

What are the differences between npm and npx ?

Auth Boiler Plate with Node.js-Logout

|

Boiler Plate with Node.js - Logout


Logout

  1. logout route 생성
  2. 로그아웃 하려는 유저 검색
  3. 해당 유저의 토큰 삭제
app.get('/api/users/logout', auth, (req, res) => {
  User.findOneAndUpdate({ _id: req.user._id }, { token: '' }, (err, user) => {
    if (err) return res.json({ success: false, err });
    return res.status(200).send({
      success: true,
    });
  });
});

auth 미들웨어를 통과한 user의 id를 통해 해당 유저를 검색하고 token을 찾아서 지운다

미리 만들어놓은 login api로 로그인을 하고 logout을 테스트해본다

성공

이제 DB에 실제로 token이 지워졌는지 확인을 해본다

DB확인

성공~~🖖



참고 자료


기초 노드 리액트 강의 - John Ahn

Auth Boiler Plate with Node.js-Authentication

|

Boiler Plate with Node.js - Authentication


Authentication

사용자가 제한된 페이지 접근시 로그인된 유저인지 혹은 관리자인지 등을 체크할 수 있는 auth route를 만든다

글 작성, 삭제 등 제한된 액션을 취할때에도 권한이 있는지 여부를 체크할 수도 있다

  1. 클라이언트는 쿠키의 토큰을 서버에 전송한다

  2. 서버에서는 토큰을 decode하여 나온 user ID로 DB에서 해당 유저를 찾는다
  3. 클라에게 받은 토큰과 DB에서 검색한 유저의 토큰을 비교한다
  4. 일치 여부에 맞는 액션을 취한다

먼저, root folder에 middleware 폴더를 만들고 그 안에 auth.js 파일을 만든다

미들웨어가 없으면 무수히 생성될 api 들을 관리하기가 어려워진다

// auth.js

const { User } = require('../models/User');

let auth = (req, res, next) => {
  // 인증 처리

  // 클라의 쿠키에서 토큰을 가져옴
  let token = req.cookies.x_auth;

  // 토큰을 복호화 후 유저를 찾음
  User.findByToken(token, (err, user) => {
    if (err) throw err;
    // 유저가 없으면 인증 no
    if (!user) return res.json({ isAuth: false, error: true });

    // 유저가 있으면 인증 ok
    // requst에 토큰과 유저를 담아서 index에서 사용
    req.token = token;
    req.user = user;
    next();
  });
};

module.exports = { auth };

위의 findByToken은 토큰으로 해당 유저를 검색하는 메소드로 User.js에서 정의한다

// User.js

userSchema.statics.findByToken = function (token, cb) {
  var user = this;

  // Token decode => id
  jwt.verify(token, 'secretToken', function (err, decoded) {
    // 유저 아이디로 해당 유저 검색 후 클라의 토큰과 DB의 토큰 일치 여부를 확인
    user.findOne({ _id: decoded, token: token }, function (err, user) {
      if (err) return cb(err);
      cb(null, user);
    });
  });
};
// index.js

const { auth } = require('./middleware/auth');

app.get('/api/users/auth', auth, (req, res) => {
  // 미들웨어 통과 => auth 통과
  res.status(200).json({
    _id: req.user._id,
    // 0 : 일반, 1 이상 : 관리자
    isAdmin: req.user.role === 0 ? false : true,
    isAuth: true,
    email: req.user.email,
    name: req.user.name,
    lastname: req.user.lastname,
    role: req.user.role,
    image: req.user.image,
  });
});



참고 자료


기초 노드 리액트 강의 - John Ahn

Auth Boiler Plate with Node.js-JWT

|

Boiler Plate with Node.js - JWT


JSON Web Token

지난번 포스팅의 token 생성 부분을 이어서 작성한다

클라이언트가 보낸 요청의 이메일이 있으면 genToken 메소드를 사용해 토큰을 생성하고 그것을 쿠키에 담는다

쿠키에 담던 로컬스토리지에 담던 세션에 담던 각각의 장단점이 있지만 여기선 쿠키에 담기로 한다

먼저 token을 만들기 위한 JWT 패키지를 설치한다

npm i --save jsonwebtoken

그러고 User.js Model에 메소드를 추가하자

const jwt = require('jsonwebtoken');

userSchema.methods.genToken = function (cb) {
  var user = this;

  // JWT로 토큰 생성
  var token = jwt.sign(user._id.toHexString(), 'secretToken');

  user.token = token;
  user.save(function (err, user) {
    if (err) return cb(err);
    cb(null, user);
  });
};

secretToken 부분은 임의로 정하면되고, 헥스코드로 변형한 user의 id와 secretToken을 합하여 토큰을 만든다

생성된 토큰을 스키마의 user token 컬럼에 추가하고 user를 save하고 콜백으로 user를 반환한다


쿠키를 생성하거나 요청의 쿠키값을 추출하게 해주는 cookie-parser 패키지를 설치한다

npm i --save cookie-parser

const cookieParser = require('cookie-parser'); // cookie-parser 패키지

app.use(cookieParser()); // cookie-parser 사용

app.post('/api/users/login', (req, res) => {
  // 클라가 요청한 이메일을 DB에서 검색
  User.findOne({ email: req.body.email }, (err, user) => {
    if (!user) {
      return res.json({
        loginSuccess: false,
        message: '아이디가 일치하지 않습니다',
      });
    } else {
      // 이메일이 DB에 있으면 비밀번호 대조
      user.comparePassword(req.body.password, (err, isMatch) => {
        if (!isMatch)
          return res.json({
            loginSuccess: false,
            message: '비밀번호가 일치하지 않습니다',
          });

        // 비밀번호 맞으면 Token 생성
        user.genToken((err, user) => {
          if (err) return res.status(400).send(err);

          // Token을 쿠키에 저장
          res
            .cookie('x_auth', user.token)
            .status(200)
            .json({ loginSuccess: true, userId: user._id });
        });
      });
    }
  });
});

비밀번호 대조에 성공하면 반환받은 user에서 토큰을 꺼내어 쿠키에 저장 후 성공 여부를 JSON으로 응답한다

토큰생성

로그인 성공



참고 자료


기초 노드 리액트 강의 - John Ahn

2021-04-29 TIL

|

2021-04-29 TIL


  • 오늘 한 것
    1. 학원 대면수업 (15:30~22:00) 프로젝트 기간
    1. 어드민 이벤트 관리 유효성 검사 추가 - 글 등록 또는 글 수정시 유효성 검사 부분이 없어서 null 값이 그대로 전송되는 이슈가 발생했다. 급하게 유효성 검사 로직을 세우고 걸러냈는데 문제는 텍스트가 아니라 이미지 수정이었다. 이미지 수정 없이 텍스트만 수정하고 업데이트 버튼을 누르면 백엔드쪽이 터져버린다. 그렇다고 해서 글 수정시 무조건적으로 이미지도 수정하게끔 유도할 수는 없다. 이 부분은 백엔드 팀원이 조금 더 힘을 써줘야한다.
    2. 어드민 판매현황, 통계 병합 - 판매현황에서 기간별 현황과 일자별 현황을 조회할 수 있도록 페이지를 만들었지만 내가 생각했던 부분이 DB에 없어서 데이터를 뽑아올 수가 없었다. 현재 DB 수정을 최소로 하면서 프로젝트를 진행중이라 지금의 DB에 맞춰서 view를 그리는 방향으로 생각을 한 결과, 판매현황 페이지와 통계 페이지를 병합하기로 결정했다. 판매현황의 일자별 현황을 통계 페이지에 삽입했다.
    3. 어드민 대시보드 차트 출력 - 백엔드에서 보낸 데이터로 오늘 날짜 기준 과거 일주일의 데이터를 차트로 그리는 작업을 완료했다. 부트스트랩 템플릿에서 제공한 차트를 뜯어고칠려니 어려움이 많았지만 결국 차트 그리기에 성공했다.
    4. Auth boiler plate with node.js - JWT를 사용해서 토큰을 생성하는 법을 배웠는데 생각보다 무척이나 간단했다. 지금 진행하는 Spring MVC 프로젝트에서는 JWT 적용이 어렵다고 들었는데 Node.js로는 그다지 어려움 없이 구현이 가능했다. 또, 제한된 페이지 및 권한 확인을 위한 auth 미들웨어도 만들었는데 여기서 토큰으로 해당 유저를 판별한다. 마지막으로 logout 기능 구현을 했다. logout은 너무 간단해서 …

  • 내일 할 것
    1. 학원 대면수업(15:30~22:00) 프로젝트 기간
    2. 어드민 백엔드 연동
    3. boiler plate with react, node.js 수강



  • 끝으로

node로 대략적인 서버 구현은 끝이고 내일부터는 react로 view를 그린다.

오늘의 한 줄 총평 : 재밌겠다