1차 프로젝트 팀이 구성됐고 다음주면 진짜 프로젝트 시작이다. 알고있는 것이 너무 없어서 팀원들에게 민폐가 될까 걱정이다.
그렇지만.. 당당하게 무식한 감자 컨셉을 잡고 최대한 도움 될 수 있도록 모르는 것들을 많이 물어봐야겠다.
몰입 가득한 2주를 보내자! 화이팅..
+ 그리고 그만 징징거리자! 절망은 짧게하고 행동은 곧바로 실천하자. 성실하게 하루하루를 보내다보면 어느새 성장해있을 것이다.
header
: 토큰의 타입(jwt : Web Token, 즉 웹에서 사용하기 위한 스펙이므로 웹에서 문제 없이 사용할 수 있는 문자열로만 구성된 base 64 인코딩 사용), 데이터 서명 방식payload
: 전달되는 데이터 signature
: 헤더와 페이로드의 전자서명JWT의 payload는 단순히 정보를 base64 encode
-> decode시 정보 노출됨
-> 민감한 정보는 제외하고 토큰 생성 필수
서버는 JWT를 생성할 떄 비공개키를 이용하여 서명함. payload를 조작할 경우 서명이 일치하지 않기 때문에 인증 실패
Session
을 사용한 유저 로그인JWT
를 쿠키에 저장하는 경우//app.use(session(...)); 비활성화
//app.use(passport.session()); 비활성화
setUserToken = (res, user) => {
const token = jwt.sign(user, secret); //jwt 웹토큰 패키지 메소드를 통해 유저정보를 secret변수를 통해서 사인함.
res.cookie('token', token); // toekn이라는 이름의 token을 쿠키로 보내고 있음
---
router.post('/', passport.authenticate('local'), (req, res, next) => {
setUserToken(res, req.user);
res.redirect('/');
// 클라이언트는 쿠키를 res로 받고 토큰을 브라우저에 저장하게 됨
}
const JwtStrategy = require('passport-jwt').Strategy;
const cookieExtractor = (req) => {
const {token} = req.cookies;
return token; // 쿠키에서 토큰을 받아오는 절차
};
const opts = { // config
secretOrKey : secret, //직접 키를 넣으면 안되고, 환경변수 값으로 넣어야함.
jwtFromRequest : cookieExtractor,
}
module.exports = new JwtStrategy(opts, (user, done) => { done(null, user) // new JwtStrategy(config, callback) 구조
)};
---
passport.use(jwt)
app.use ((req, res, next) => {
if (!req.cookies.token) {
next();
return;
}
return passport.authenticate('jwt)(req,res,next);
});
res.cookie('token', null, {maxAge:0,});
SMTP 서버 이용 (네이버, 구글 등의 메일 서버)
-> 직접 구현 필요
메일 발송 서비스 이용
-> 메일 발송 API 제공 및 관리용 웹페이지, 사용량에 따라 유료 과금
Simple Mail Transfer Protocol
Nodemailer
패키지를 사용하여 SMTP 서버를 통해 메일을 발송할 수 있음
const nodemailer = require('nodemailer');
const transport = nodemailer
.createTransport({
service: 'Gmail',
auth:{
user: "google account",
pass: "app password",
};
});
const message = {
from: "login account", //발송 메일 주소
to: "mail address", // 수신 메일 주소
subject: "title", // 제목
text: "message" // 내용
};
transport.sendMail( message, (err, info) => {
if(err) { // sendMail은 콜백 활용 -> 어싱크나 프로미스로 전환 가능)
console.error('err',err);
return;
}
console.log('ok', info);
})
function generateRandomPassword(){
return Math.floor(
Math.random() * (10 ** 8)).toString().padStart('0',8);
}
---
router.post('/reset-password',
asyncHandler(... => {
const { email } = req.body;
const randomPassword = generateRandomPassword();
await User.findOneAndUpdate({email}, {password : getHash(randomPassword),
});
await sendEmail(email, '...', randomPassword);
res.redirect('/');
}));
///비밀번호 변경
const UserSchema = ...
passwordReset: {
type: Boolean,
default : false,
}
...
---
router.post('/reset-password', ...
await User.findOneAndUpdate({
...
passwordReset: true,
});
function checkPasswordReset(req, res, next) {
if(req.user && req.user.passwordReset){
res.redirect('/update-password');
return;
}
next();
}
---
router.post('/update-password', ...
await User.findOneAndUpdate({
...
passwordReset: false,
});
passport-google-oauth20
은 손쉽게 구글 OAuth 2.0을 구현해주는 패키지 const GoogleStrategy = require("passport-google-oauth20").Strategy;
const config = {
clientID : 'clientID',
clientSecret: 'clientSecret',
callbackURL: 'callbackUrl',
}
...
new GoogleStrategy(config, (accessToken, refreshToken, profile, done) => { const {email, name } = profile._json;
.. })
passport.use(google);
---
router.get('/google', passport.authenticate('google', {
scope: ['profile', 'email']
}));
최근 신규 프로젝트에서 가장 많이 채택되고 있는 웹 서버 소프트웨어
웹 서버 소프트웨어란, HTTP요청을 받아 파일이나 프로그램 실행 결과를 HTTP 응답으로 보내주는 소프트웨어
JAVA : Tomcat
PHP : fastcgi등
다른 언어가 HTTP요청을 처리하기 위한 의존성이 있는 것에 반해, Node.js는 기본적으로 HTTP요청을 수신하고 응답하는 기능이 이미 있음.
-> 웹 서버 소프트웨어 없이도 스스로 동작 가능
그러나,
reverse-proxy
기능을 사용해, Node.js와 Nginx를 연결할 수 있음.reverse-proxy
는 HTTP요청을 다른 서버에 전달하는 기능server {
listen 80;
server_name www.example.com;
location / {
proxy_pass http://localhost: 3000;
proxy_http_version 1.1;
}
}