validate - next()
함수로 사용했을 경우? 콜백함수가 잘 호출된다.
함수로 사용이 아닌, 변수에 할당해서 모듈화를 했다면, 콜백함수가 호출되지 않고 response가 무한로딩된다.
모듈 선언 + response 보내고, 끝낸다고 파악하기 때문에 > 다음 콜백함수를 사용하라고 선언해준다.
router 매개변수 req, res + `next`
validate 모듈에서 에러가 발생하지 않는다면 next()로 다음 인자 할일인 콜백함수 호출하기
const validate = (req, res, next) => {
const err = validationResult(req);
if (!err.isEmpty()) return res.status(400).json(err.array());
else return next();
};
validate 매개변수 express 에서 알아서 넣어준다.
users 유효성 검사 정리
body email 형식? `.isEmail()` > 사용이 불가능 하다면 정규표현식으로 형식 규격 정해놓는다.
`.isStrongPassword()` 강력한 암호(특수문자 난리난 자동암호)
channels와 비슷한 유효성검사 로직 리팩토링 진행해준다.
로그인
인증, 인가
Authentication 인증 = 로그인
구매, 마이페이지 등
Authorization 인가
관리자 / 고객 등 접근 권한 관리
쿠키 Cookie, 세션 Session
쿠키
(포춘) 쿠키에 필요한 내용을 직접 넣어서 서버 - 클라이언트가 소통
웹 서버 쿠키를 구워준다 > 웹 브라우저에 주면, 브라우저가 자기 메모리에 저장해두고 > 다음에 같은 웹서버 방문할 때 쿠키 들고 요청함
최초에 굽고, 이후는 핑퐁만!
장점 : 서버가 저장 X > 서버 저장공간, HTTP (Stateless = 서버 상태저장하지 않는다.= RESTful)
단점 : 보안에 취약
세션
쿠키의 보안 문제를 해결!
중요한 정보는 서버의 금고 (Session)에 저장해두고, 그 정보가 어디있는지 주소(Session ID)만 적어서 쿠키에 담는다,
서버 - 클라이언트 는 ID 번호만 가지고 소통한다.
장점 : 보안이 비교적 좋다
단점 : 서버가 저장 O > Stateless X
JWT Json Web Token
쿠키와 세션의 장점 합친!
개념 : Json 형태의 데이터를 안전하게 전송하기 위한 (웹에서 사용하는) 토큰
토큰 : 인증 + 인가
== 토큰을 가진 사용자가 "증명"을 하기 위한 수단
장점
- 보안에 강하다 = 암호화가 되어있다.
- 서버가 상태를 저장하지 않는다 `Stateless`하다 > HTTP 특징을 잘 따랐다
- 서버 부담을 줄여줄 수 있다
*토큰을 발행하는 서버를 따로 만들어줄 수도 있다!
JWT.io
암호화 + 복호화(디버깅)
`.`으로 구분되어 있고, HEADER, PAYLOAD 부분에 데이터가 들어있으며, 복호화한다
HEADER에 암호화 알고리즘 종류를 제공한다.
구조
헤더 : 토큰을 암호화 하는데 사용한 알고리즘, 토큰의 형태(jwt)
페이로드 : 사용자 정보(이름, 주소, 핸드폰,...비밀번호 X)
서명 : 페이로드 값이 바뀌면, 서명값 통째로 변화하기 때문에 JWT 를 믿고 사용할 수 있다.
인증/인가 하는 절차
- 로그인 요청 POST /login > body - username, password
- 서버 내부 로직 확인
- JWT 토큰 발행 (시점)
- 로그인 성공 : 로그인 당분간 유지하고 > JWT 토큰 동봉, 다음 요청때 사용해서 서명값 체크하고 로그인 성공시킴
- 다른 요청 > header - JWT : 이미 인증된 유저
- 서버에서 내가 한 서명이 맞는지 확인
- 로그인 성공 OR 블락
jsonwebtoken 구현하기
`npm i jsonwebtoken`
코드에서 검증 확인
검증 성공하면 페이로드 값을 확인할 수 있다.
`iat` 토큰 발행 시간 issued at : 페이로드,서명값 수시로 변경된다.
var jwt = require('jsonwebtoken'); //jwt 모듈 호출
var token = jwt.sign({ foo: 'bar' }, 'shhhhh'); //jwt 서명 메서드
//토큰 생성 > jwt 서명 (foo : payload, 'shhhhh' : 나만의 암호키) + SHA256
console.log(token);
//검증 - 성공하면 페이로드 값 확인가능
var decoded = jwt.verify(token, 'shhhhh');
console.log(decoded) // bar
//console
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJmb28iOiJiYXIiLCJpYXQiOjE3MTU2NjUwMjN9.-hGHG4tq808IbIAOmobIqpG_PodKtTiz9kNOxrxtb58
{ foo: 'bar', iat: 1715665023 }
나만의 암호키 보호하는법
문자열, 다른 파일 또는
깃허브에 올리지 않는, 설정파일에 환경변수 설정함
`.env` = environment : 환경변수 설정 값
.env
개념 : 포트넘버, DB 게정, 암호키 등등 외부에 유출되면 안되는 중요한 환경 변수를 따로 관리하기 위한 파일
> 깃허브에 올라가면 안되는 값
파일 확장자 : .env, .txt, .jpg
`npm i dotenv`
환경변수파일 > 프로젝트 최상위 패키지 존재
//.env
PORT = 1234 #express 포트 넘버
PRIVATE_KEY ='shhhhh' # JWT 암호키
//jwt.js
var dotenv = require("dotenv");
dotenv.config();
var token = jwt.sign({ foo: "bar" },process.env.PRIVATE_KEY);
//express.js
const dotenv = require("dotenv");
dotenv.config();
app.listen(process.env.PORT);
.gitignore에 .env 파일 추가
youtube-demo 실습
//jwt 모듈 세팅
const jwt = require("jsonwebtoken");
//dotenv 모듈
const dotenv = require("dotenv");
dotenv.config();
//...
const token = jwt.sign(
{ email: loginUser.email, name: loginUser.name },
process.env.PRIVATE_KEY
);
//res.cookie();
res
.status(200)
.json({
message: `${loginUser.name}님 로그인 되었습니다.`,
token: token,
});
//...
토큰이 잘 발행되는걸 확인할 수 있다.
토큰을 Cookies 탭에 넣어서 사용해보자
☑️ 배운 점
JWT 토큰에서 access 토큰과 refresh 토큰이 있는걸로 알고 있는데, refresh 토큰을 이용해서 로그인 개발을 해보고 싶다.
유효성 검사 next(); 사용법
쿠키, 세션, JWT 차이점