저번에 만들었던 express 서버에서 회원가입과 로그인을 구현해 보겠습니다.
로그인 인증은 token을 쿠키로 보내는 방식으로 하려고 합니다.
bcrypt와 jsonwebtoken을 설치해줍니다.
yarn add bcrypt
yarn add jsonwebtoken
./routes/auth.js 파일을 만들어줍니다.
const express = require('express');
const bcrypt = require('bcrypt'); // 암호화
const jwt = require('jsonwebtoken'); // 토큰
const { User } = require('../models'); // User 테이블
const router = express.Router();
router.post('/signup', async (req, res, next) => {
const { email, nick, password } = req.body;
// req.body로 email, nick, password를 가지고 옵니다.
try {
// 이미 email이 있는 경우를 방지
const exUser = await User.findOne({ where: { email } });
if (exUser) {
res.status(500).json({ error: '중복되는 이메일입니다.' });
}
// bcrypt로 password를 암호화해줍니다.
const hash = await bcrypt.hash(password, 12);
await User.create({
email,
nick,
password: hash,
});
return res.status(200).json({success: 'true'});
} catch (error) {
console.error(error);
return next(error);
}
});
module.exports = router;
app.js 에 auth.js 를 추가 해줍니다.
var express = require('express');
var path = require('path');
var cookieParser = require('cookie-parser');
var logger = require('morgan');
var indexRouter = require('./routes/index');
var usersRouter = require('./routes/users');
// 추가
var authRouter = require('./routes/auth');
const { sequelize } = require('./models');
var app = express();
sequelize.sync();
app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
app.use('/', indexRouter);
app.use('/users', usersRouter);
// 추가
app.use('/auth', authRouter);
module.exports = app;
postman과 mySQLWorkbench로 확인해 볼게요.
token을 만들 때 보안을 위해 비밀키를 사용하도록 하겠습니다.
dotenv를 설치해주세요
yarn add dotenv
.env 파일에 비밀키를 넣어주세요. 어떤 문자열도 괜찮습니다.
JWT_SECRET=secretkey_jwt!!
사용할 때는 process.env 에 .env 파일에 키 값을 붙이는 형식입니다.
여기서는 process.env.JWT_SECRET
app.js에서 dotenv를 실행시켜줍니다.
const express = require('express');
const path = require('path');
const cookieParser = require('cookie-parser');
const logger = require('morgan');
require('dotenv').config();
/*중략*/
./routes/auth.js 에 login을 세팅해줍니다.
const express = require('express');
const bcrypt = require('bcrypt');
const jwt = require('jsonwebtoken');
const { User } = require('../models');
const router = express.Router();
/*중략*/
router.post('/login', async (req, res, next) => {
const { email, password } = req.body;
// email, password 값을 받아옵니다.
User.findOne({
where: {
email,
},
}).then((user) => {
if (!user) {
return res.status(404).json({ emailnotfound: 'Email not found' });
}
// password 비교
bcrypt.compare(password, user.password).then((isMatch) => {
if (isMatch) {
const payload = {
id: user.id,
nick: user.nick,
};
//jwt 객체가 sign() 메서드를 호출해서 토큰을 생성합니다
jwt.sign(
payload,
process.env.JWT_SECRET,
{
// token의 지속시간
expiresIn: '24h',
},
(err, token) => {
// res.cookie('키', '값')은 cookie에 키 값을 넣는 방식입니다.
res.cookie('token', token);
// res.json으로 값을 확인 해보겠습니다.
res.json({
nick: user.nick,
id: user.id,
token: token,
});
},
);
} else {
return res
.status(400)
.json({ passwordincorrect: 'Password incorrect' });
}
});
});
});
module.exports = router;
postman을 통해 값을 확인해보겠습니다.
JWT 웹페이지에서 token 값을 decode 해보겠습니다.
정확하게 decode 되는 걸 확인 할 수 있습니다.
express 서버를 react와 연결 해보겠습니다.
기본적인 세팅은 생략하도록 할게요.
react를 세팅하기 전에 서버에 cors를 먼저 세팅하겠습니다.
cors가 필요한 이유는 express에서 사용하는 서버 주소와 react에서 사용하는 클라이언트 주소가 다르기 때문입니다. 서로 주소가 다를 때 일어날 수 있는 보안의 문제 때문에 세팅을 해줄 필요가 있습니다.
yarn add cors
var express = require('express');
var path = require('path');
var cookieParser = require('cookie-parser');
var logger = require('morgan');
// cors 추가
const cors = require('cors');
require('dotenv').config();
var indexRouter = require('./routes/index');
var usersRouter = require('./routes/users');
var authRouter = require('./routes/auth');
const { sequelize } = require('./models');
var app = express();
sequelize.sync();
app.use(
cors({
origin: 'http://localhost:3000', // 허락하고자 하는 요청 주소
credentials: true, // true로 하면 설정한 내용을 response 헤더에 추가 해줍니다.
}),
);
/* 중략 */
axios를 통해서 email, nick, password를 서버로 보내보겠습니다.
회원가입을 React에서 해볼게요
test로 회원가입 됨을 확인 할 수 있습니다.
axios를 통해서 email, password를 서보로 보내 보겠습니다.
로그인을 해볼게요.
return 받은 값을 console에서 확인 해보겠습니다.
쿠키로 보낸 토큰도 확인 됩니다.