프로젝트 1 - 로그인 기능
⭐프로젝트 1 - 로그인 기능
📕로그인 기능
우선 로그인 라우터가 필요하다
이 로그인 라우터에서 해야할 일은 3가지가 있다
-
DB에서 요청한 이메일 찾기
-
DB에서 요청한 이메일이 있다면 비밀번호가 같은지 확인하기
-
비밀번호까지 같다면 토큰 생성하기
`app.post('/login', (req, res) => { 여기 }`
위 코드를 index.js에 작성하고
여기 안에 아래 3가지 코드를 각각 추가하면 된다
📗DB에서 요청한 이메일 찾기
DB에서 찾기위해서 우선 유저 모델을 가져온다
이후 몽고DB에서 제공하는 메소드인 .findOne() 을 사용한다
그리고 해당하는 유저가 없다면 로그인이 실패했다고 JSON으로 리턴하자
app.post('./login', (req, res) => {
User.findOne({ email: req.body.email }, (err, user) => {
if(!user) {
return res.json({
loginSuccess: false,
message: "해당 이메일에 해당하는 유저가 없습니다."
})
}
})
}
유저가 있다면 아래 기능으로 넘어간다
📘비밀번호가 같은지 확인하기
지금 우리가 비밀번호를 저장할 때 Bcrypt로 암호화를 해서 저장한다
단방향으로만 진행되기 때문에 암호화된 암호를 복호화할 수 없다
그래서 사용자가 입력칸에 친 plainPassword가 DB에 있는 비밀번호와 같은지
비교하기 위해서는 plainPassword를 암호화 한 후에 비교를 해야한다
그래서 bcrypt.compare 을 사용할 것이다
그러기 위해서 comparePassword라는 메소드를 만들어야 한다
인자로는 req.body.password로 plainPassword하나를 넣고,
두번째로는 콜백 함수를 넣을 것이다
콜백은 에러가 났을 경우 리턴할 err과 암호화된 비밀번호와 순수한 비밀번호가
맞는지 아닌지를 알려주는 isMatch를 넣을 것이다
isMatch는 true, false로 리턴된다
User.js에서 메소드를 먼저 만들자
userSchema.methods.comparePassword = function(plainPassword, cb) {
bcrypt.compare(plainPassword, this.password, function(err, isMatch) {
if(err) return cb(err)
cb(null, isMatch)
})
}
이렇게 작성을 하고 index.js에 아래의 코드를 넣자
app.post('/login', (req, res) => {
User.findOne({ email: req.body.email }, (err, user) => {
if(!user) {
return res.json({
loginSuccess: false,
message: "해당 이메일에 해당하는 유저가 없습니다."
})
}
user.comparePassword(req.body,password, (err, isMatch) => {
if(!isMatch){
return res.json({
loginSuccess: false,
message: "비밀번호가 틀렸습니다."
})
}
})
})
})
만약 isMatch가 true가 아니라면 로그인이 실패한 것이고, 실패했다고 리턴하면 된다
📙비밀번호가 같다면 토큰 생성하기
토큰 생성을 위해서 JSONWEBTOKEN 라이브러리를 다운받아야 한다
npm install jsonwebtoken --save
위에서 메소드를 만든 것 처럼 토큰을 발행하는 메소드를 따로 만들어야 한다
그리고 메소드를 만드는 과정은 사이트를 확인하면 과정이 잘 나와있다
사이트를 참조하면서 User.js에 메소드를 만들어보자
userSchema.methods.generateToken = function(cb){
let user = this
let token = jwt.sign(user._id.toHexString(), 'secretToken');
user.token = token
user.save(function(err, user){
if(err) return cb(err)
cb(null, user)
})
}
user._id 와 secretToken을 합치면 token을 만드는 것이다
token을 해석을 할 때 secretToken을 넣으면 user._id가 나오게 된다
token을 user에 넣어서 리턴하자
이제 위의 메소드를 index.js에서 사용해야 한다
index.js에서 사용하는 과정은 아래와 같다
만약 에러가 리턴 됐다면 status(400)을 리턴하는거고 이건 오류를 의미한다
그리고 토큰을 저장해야하는데 쿠키, 로컬스토리지등등 저장할 수 있다
우리는 쿠키에 저장하도록 하자
쿠키에 저장하려면 라이브러리를 하나 다운받아야 하는데 바디파서처럼
쿠키파서라는 라이브러리를 다운받아야한다
npm install cookie-parser --save
그리고 상단에 const cookieParser = require('cookie-parser')와
app.use(cookieParser())을 추가하자
그리고 쿠키를 이용해서 토큰을 저장하자
app.post('/login', (req, res) => {
User.findOne({ email: req.body.email }, (err, user) => {
if(!user) {
return res.json({
loginSuccess: false,
message: "해당 이메일에 해당하는 유저가 없습니다."
})
}
user.comparePassword(req.body,password, (err, 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
})
})
})
})
})
지난 강에서 [email protected]이랑 1234abcd로 회원가입을 했다
이걸 사용해서 postman에서 로그인을 해보자
http://localhost:3000/login
으로 포스트 메소드로 세팅해놓자
이후 body에 raw, JSON으로 선택하고 여기에 정보를 입력하면 된다
{
"email": "[email protected]",
"password": "1234abcd"
}
이렇게 해서 send를 해보자
그러면 제대로 JSON이 나오는 것을 볼 수있다
코드가 헷갈릴 수 있어서 전문을 넣도록 하겠다
📔코드
index.js
const express = require('express')
const app = express()
const port = 3000
const mongoose = require('mongoose')
const { User } = require("./models/User")
const bodyParser = require('body-parser')
const config = require('./config/key')
const cookieParser = require('cookie-parser')
app.use(bodyParser.urlencoded({extended: true}))
app.use(bodyParser.json())
app.use(cookieParser())
mongoose.connect(config.mongoURI
).then( () => console.log('MongoDB Connected'))
.catch(err => console.log(err))
app.get('/', (req, res) => {
res.send('Hello World! BooKi')
})
app.post('/signup', (req, res) => {
//회원 가입 할 때 작성한 정보들을 가져와 DB에 넣어준다
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
})
})
})
app.post('/login', (req, res) => {
User.findOne({ email: req.body.email }, (err, user) => {
if(!user) {
return res.json({
loginSuccess: false,
message: "해당 이메일에 해당하는 유저가 없습니다."
})
}
user.comparePassword(req.body.password, (err, 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
})
})
})
})
})
app.listen(port, () => {
console.log(`http://localhost:${port}/`)
})
user.js
const mongoose = require('mongoose')
const bcrypt = require('bcrypt')
const saltRounds = 10
const jwt = require('jsonwebtoken')
const userSchema = mongoose.Schema({
name: {
type: String,
maxlength: 50
},
email: {
type: String,
trim: true,
unique: 1
},
password: {
type: String,
minlength: 5
},
role: {
type: Number,
default: 0
},
image: String,
token: {
type: String
},
tokenExp:{
type: Number
}
})
userSchema.pre('save', function(next){
let 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()
}
})
userSchema.methods.comparePassword = function(plainPassword, cb) {
bcrypt.compare(plainPassword, this.password, function(err, isMatch) {
if(err) return cb(err)
cb(null, isMatch)
})
}
userSchema.methods.generateToken = function(cb){
let user = this
let token = jwt.sign(user._id.toHexString(), 'secretToken');
user.token = token
user.save(function(err, user){
if(err) return cb(err)
cb(null, user)
})
}
const User = mongoose.model('User', userSchema)
module.exports = { User }
Author And Source
이 문제에 관하여(프로젝트 1 - 로그인 기능), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@qnrl3442/프로젝트-1-로그인-기능저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)