인자를 객체로 넘겼다고 에러가 뜨는데, auth를 구현하는 app.get에서 자꾸 문제가 있다고 합니다. 오타는 도저히 못찾겠는데,, 문제가 무엇일까요
const express = require('express')
const app = express()
const port = 5000
const bodyParser = require('body-parser');
const { User } = require("./models/User");
const config = require('./config/key');
const cookieParser = require('cookie-parser');
const auth = require('./middleware/auth');
// application / x-www-form-urlencoded
app.use(bodyParser.urlencoded({extended : true}));
// application / json
app.use(bodyParser.json());
app.use(cookieParser());
const mongoose = require('mongoose');
//mongoDB 연결
mongoose.connect(config.mongoURI,{
useNewUrlParser: true, useUnifiedTopolongy: true, useCreateIndex: true, useFindAndModify: false
}).then(() => console.log('MongoDB connected !'))
.catch(err => console.log('MongoDB Error !'));
//Hello world 출력
app.get('/', (req, res) => {
res.send('Hello World!')
});
//register 라우트
app.post('/api/users/register', (req, res) => {
// 회원가입 할 때 필요한 정보들을 client으로부터 받아오면
// 그것들을 database에 넣어준다.
const user = new User(req.body)
user.save((err, userInfo) => {
if(err) return res.json({ success : false, err })
return res.status(200).json({
success: true
});
});
});
// login 라우트
app.post('/api/users/login', (req, res) => {
// console.log('ping')
//요청된 이메일을 데이터베이스에서 있는지 찾는다.
User.findOne({ email: req.body.email }, (err, user) => {
// console.log('user', user)
if (!user) {
return res.json({
loginSuccess: false,
message: "제공된 이메일에 해당하는 유저가 없습니다."
})
}
//요청된 이메일이 데이터 베이스에 있다면 비밀번호가 맞는 비밀번호 인지 확인.
user.comparePassword(req.body.password, (err, isMatch) => {
// console.log('err',err)
// console.log('isMatch',isMatch)
if (!isMatch)
return res.json({ loginSuccess: false, message: "비밀번호가 틀렸습니다." })
//비밀번호 까지 맞다면 토큰을 생성하기.
user.generateToken((err, user) => {
if (err) return res.status(400).send(err);
// 토큰을 저장한다. 어디에 ? 쿠키 , 로컳스토리지
res.cookie("x_auth", user.token)
.status(200)
.json({ loginSuccess: true, userId: user._id })
})
})
})
})
// auth 라우트 (미들웨어로 사용될 것입니다.)
app.get('/api/users/auth', auth, (req, res) => {
//여기 까지 미들웨어를 통과해 왔다는 얘기는 Authentication 이 True 라는 말.
res.status(200).json({
_id: req.user._id,
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
})
})
app.get('/api/users/logout', auth, (req, res) => {
// console.log('req.user', req.user)
User.findOneAndUpdate({ _id: req.user._id },
{ token: "" }
, (err, user) => {
if (err) return res.json({ success: false, err });
return res.status(200).send({
success: true
})
})
})
// 포트를 통해 index.js 를 실행합니다.
app.listen(port, () => {
console.log(`Example app listening at http://localhost:${port}`)
});
위는 index.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;
if (!user) return res.json({ isAuth: false, error: true })
// console.log('userh', user)
req.token = token;
req.user = user;
next();
})
}
module.exports = { auth };
auth.js
// 모듈 (User에서는 데이터 베이스를 위한 몽구스, 유저의 비밀번호 암호화를 위한 비크립트, 유저의 개개인 토큰을 얻기 위한 제이슨웹토큰을 가져온다.)
const mongoose = require('mongoose');
const bcrypt = require('bcrypt');
const jwt = require('jsonwebtoken');
// 비밀번호 암호화를 위한 salt 값 설정. salt 값은 암호화된 비밀번호를 해킹하기 어렵게 만들 수 있음.
const saltRounds = 10;
// 유저의 정보들을 객체화, 이른 바 유저 스키마를 생성한다. ( 몽구스의 메소드 )
// 각 유저들의 이름, 이메일, 비밀번호 등 개인정보를 담기 위한 객체임.
const userSchema = mongoose.Schema({
name : {
type: String,
maxlength: 50
},
email : {
type: String,
trim: true,
unique: 1
},
password : {
type: String,
minlength: 5
},
lastname : {
type: String,
maxlength: 50,
},
role : {
type: Number,
default: 0
},
token: {
type: String,
},
tokenExp: {
type: Number
},
image : String
})
// 유저 스키마 이전에 실행될 것임.
userSchema.pre('save', function (next) {
var user = this;
if (user.isModified('password')) {
//비밀번호를 암호화 시킨다.
bcrypt.genSalt(saltRounds, function (err, salt) {
if (err) return next(err)
bcrypt.hash(user.password, salt, function (err, hash) {
if (err) return next(err)
user.password = hash
next()
})
})
} else {
next()
}
})
// comparePassword 라는 이름의 유저 스키마 메소드를 생성합니다. ( 당연히 비밀번호 비교를 위한 메소드이겠지요? )
userSchema.methods.comparePassword = function (plainPassword, cb) {
//plainPassword 1234567 암호회된 비밀번호 $2b$10$l492vQ0M4s9YUBfwYkkaZOgWHExahjWC
bcrypt.compare(plainPassword, this.password, function (err, isMatch) {
if (err) return cb(err);
cb(null, isMatch);
})
}
userSchema.methods.generateToken = function (cb) {
var user = this;
// console.log('user._id', user._id)
// jsonwebtoken을 이용해서 token을 생성하기
var token = jwt.sign(user._id.toHexString(), 'secretToken')
// user._id + 'secretToken' = token
// ->
// 'secretToken' -> user._id
user.token = token
user.save(function (err, user) {
if (err) return cb(err)
cb(null, user)
})
}
userSchema.statics.findByToken = function(token, cb) {
var user = this;
// 토큰을 decode 한다.
jwt.verify(token, 'secretToken', function(err, decoded) {
// 유저 아이디를 통해서 유저를 찾은 다음에
// 클라이언트에서 가져온 token과 DB에서 가져온 토큰이 일치하는지 확인합니다.
user.findOne({ "_id" : decoded, "token" : token }, function(err, user) {
if(err) return cb(err);
cb(null, user);
})
})
}
// 유저스키마 => User 라는 이름으로 모델화.
const User = mongoose.model('User', userSchema);
// 방금 모델화한 User 밖에서도 사용가능하도록 exports.
module.exports = { User };
user.js 입니다.
문제가 무엇일까요, ㅠ
덕분에 해결하였습니다 감사합니다😇