// channels3.js
//========== validate
const validate = (req, res) => { // const err 부터 ~ return 문까지 중복으로 쓰임
const err = validationResult(req) // 중복되는 내용을 vlidate 변수에 담아 함수를 하나의 모듈로서 사용
if (!err.isEmpty()) { // 오류가 있으면 실행
return res.status(400).json(err.array())
}
}
//==========
router
.route('/')
.get(
[
body('userId').notEmpty().isInt().withMessage('숫자 입력 필요') //검증내용
validate // 검증확안, 오류처리
]
, (req, res) => { ~ }
위의 코드를 실행하면 요청만 보내지고 응답을 기다리기만 하는 오류가 발생합니다.
body의 .notEmpty 이런부분은 body로 받아온 userId가 지켜야 하는 규칙을 설정한 것, 실제로 검증을 확인하고 처리하는 것은 validate에서 일어납니다.
오류가 발생하지 않았다면 다음에 무엇을 할지 알아야 하는데, 무엇을 해야하는지 정해지지 않은 상태. -> 계속 응답대기
const validate = (req, res, next) => { // 매개변수에 next를 추가 - next 함수를 받아오는 역할
const err = validationResult(req)
if (err.isEmpty()) {
return next() // 다음 함수를 찾아가라는 의미 / 다음 할 일 (미들웨어, 함수)
} else {
return res.status(400).json(err.array())
}
}
매개변수에 next를 추가하여 next함수를 받아오게 만들고,
if문에서 next()함수를 return 하여 다음 미들웨어를 실행하게 정해주었습니다.
else문은 오류발생시 상태코드400과 에러내용을 처리합니다.
추가로, 기존의 if문이 이중부정문이었던 것을 긍정/부정의 형식으로 수정하였습니다.
ex) !err.isEmpty() 에러가 없지 않을 때 실행
ex) err.isEmpty() 에러가 없을 때 실행
미들웨어 : 요청과 응답의 중간(middle)의 위치에서 동작하기에 미들웨어라고 합니다.
요청과 응답을 컨트롤하고, 부적절한 요청을 판단합니다.
주소가 없을 때 : app.use((req, res, next() => {}) 는 모든 요청에서 실행
실행 주소가 있을 때 : app.get('/', (req, res, next() => {}) get메서드의 / 요청에서만 실행
p.246 참고 할 것 (node.js)
인증 (Authentication)
무언가를 확인하거나 확증하는 행위.
ex) 로그인하여 해당 사이트의 유저인 것을 인증
인가 (Authorization)
어떠한 행위에 대한 허가.
ex) 사이트의 회원이지만, 관리자페이지에 접근할 권한을 인가받지 않은 경우, 접속 불가. (인증은 되었으나, 인가받지 못함)
사이트에 접속하여 로그인 한 경우, 페이지를 이동하거나 할 때 로그인 상태를 유지하고 있을 수 있는 이유는 쿠키 덕분입니다.
클라이언트에서 요청을 보낼때 쿠키와 함께 서버에 보내지기 때문입니다.
쿠키의 동작원리
ex) 로그인
JSON Web Token
JSON 형태의 데이터를 안전하게 전송하기 위해 웹에서 사용하는 토큰입니다.
토큰은 인증기능과, 권한기능이 있습니다.
쿠키와 세션의 단점을 보완합니다.
설치
npm 에서 'jsonwebtoken'을 검색하여 설치 링크
npm i jsonwebtoken
const jwt = require('jsonwebtoken'); // jwt 모듈
const dotenv = require('dotenv'); // dotenv 모듈
dotenv.config(); // dotenv 설정 사용
// 로그인
router.post(
'/login',
[
body('email').notEmpty().isEmail().withMessage(' 이메일 확인 필요'),//비어 있지않고, 이메일형식(정규표현식)
body('password').notEmpty().isString().withMessage('비밀번호 확인 필요'),
validate
],
(req, res) => {
const { email, password } = req.body
let sql = `SELECT * FROM users WHERE email = ?`
conn.query(sql, email,
function (err, results) {
if (err) {
console.log(err)
return res.status(400).end()
}
var loginUser = results[0];
if (loginUser && loginUser.password == password) {
// token 발급
const token = jwt.sign({
emial : loginUser.email,
name : loginUser.name
}, process.env.PRIVATE_KEY_LOGIN, {
expiresIn : '5m',// 토큰만료시간
issuer : "kim" //
});
//쿠키
res.cookie("token", token, {
httpOnly: true
}) //쿠키에는 여러가지 값을 담을 수 있고, token 상자안에 token 을 담아 보냄
console.log(token);
res.status(200).json({
message: `${loginUser.name}님 로그인 되었습니다.`
})
} else {
res.status(403).json({ // 403 인증거부
message: "이메일 또는 비밀번호가 틀렸습니다."
})
}
}
)
})
ex)
res.cookie
JWT는 암호화가 되어있습니다.
jwt.io에서 링크 그 구조를 확인 할 수 있습니다.
HEADER, PAYLOAD, VERIFY SIGNATURE 3부분으로 구조가 나뉩니다.
ex)
jwt.sign (payload, secretKey, options)
환경변수로 .env 파일에 설정 값을 보관합니다.
설치
npm에서 'dotenv'을 검색하여 설치 링크
npm i dotenv