[React JS] 1. Node.js
1.Node.js
์๋ฐ์คํฌ๋ฆฝํธ๋ฅผ ํฌ๋กฌ์ด๋ IE๊ฐ ์๋ ์๋ฒ์ฌ์ด๋์์๋ ์ฌ์ฉํ ์ ์๊ฒ๋จ
java์ ๊ฐ์ด ์๋ฒ์ฌ์ด๋์์ ์ฌ์ฉํ ์์๋ javascript
Express JS?
2. boiler plate Project
3. Express.js
npm install express --save |
const express = require('express')
const app = express()
const port = 3000
app.get('/', (req, res) => {
res.send('Hello World!')
})
app.listen(port, () => {
console.log(`Example app listening on port ${port}`)
})
"scripts": {
"start": "node index.js",
"test": "echo \"Error: no test specified\" && exit 1"
}
npm run start |
4. Mongo DB ์ฐ๊ฒฐ
- mongoose ์ค์น- mongodb ์ฐ๊ฒฐ
const express = require('express')
const app = express()
const port = 3000
const mongoose = require('mongoose')
mongoose.connect('mongodb+srv://okol4561:password@first.2owuq.mongodb.net/?retryWrites=true&w=majority', {}).then(() => console.log('MongoDB Connected...')).catch(err => console.log(err))
app.get('/', (req, res) => {
res.send('Hello World!')
})
app.listen(port, () => {
console.log(`Example app listening on port ${port}`)
})
5. Model์ด๋
- Model : schema๋ฅผ ๊ฐ์ธ์ฃผ๋ ์ญํ
- Schema : ์ ๋ณด๋ค์ ์ง์
models ํด๋ ์์ฑ
User.js ํ์ผ ์์ฑ
const mongoose = require('mongoose');
const userSchema = mongoose.Schema({
name: {
type: String,
maxlength: 50
},
email: {
type: String,
trim: true,
unique: 1
},
password: {
type: String,
maxlength: 5
},
lastname: {
type: String,
maxlength: 50
},
role: {
type: Number,
default: 0
},
image: String,
token: {
type: String
},
tokenExp: {
type: Numebr
}
})
const User = mongoose.model('User', userSchema)
module.exports = { User }
6. BodyParser
- Client์ Server๊ฐ ํต์
-> Request with Body (the JSON, buffer, String and URL encoded data)
-> body ๋ฐ์ดํฐ๋ฅผ ๋ถ์(parse)ํด์ req.body๋ก ์ถ๋ ฅํด์ฃผ๋ ๊ฒ
-> body-parser dependency (์๋ฒ์์ ํด๋ผ์ด์ธํธ์ ์ ๋ณด๋ฅผ ๋ฐ์๋ body parser dependency๋ฅผ ์ด์ฉ)
npm install body-parser --save |
* client๊ฐ ์๊ธฐ ๋๋ฌธ์ POSTMAN์ ์ฌ์ฉํด์ ๋ฐ์ดํฐ ๋ณด๋ด๊ธฐ
-> Register Route๋ง๋ค๊ธฐ
const { User } = require("./models/User");
// ํด๋ผ์ด์ธํธ์์ ์ค๋ ์ ๋ณด๋ฅผ ์๋ฒ์์ ๋ถ์ํด์ ๊ฐ์ ธ์ฌ ์ ์๊ฒ ํด์ฃผ๋ ๊ฒ
const bodyParser = require('body-parser');
// application/x-www-form-urlencoded
app.use(bodyParser.urlencoded({extended: true}));
// applicaton/json
app.use(bodyParser.json());
app.post('/api/users/register',(req,res)=>{
//ํ์๊ฐ์
ํ ๋ ํ์ํ ์ ๋ณด๋ค์ client์์ ๊ฐ์ ธ์ค๋ฉด,
//๊ทธ ์ ๋ณด๋ค์ DB์ ๋ฃ์ด์ค๋ค.
const user = new User(req.body);
//user๋ชจ๋ธ์ ์ ๋ณด๊ฐ ์ ์ฅ๋จ
//์คํจ ์, ์คํจํ ์ ๋ณด๋ฅผ ๋ณด๋ด์ค
user.save().then(()=>{
res.status(200).json({
success:true
})
}).catch((err)=>{
return res.json({success:false,err})
});
})
7. Nodemon ๋ค์ด
npm install nodemon --save-dev |
- ์๋ฒ๋ฅผ ๋์ง ์์๋ ๋ฐ์์ด ๋๊ฒ๋
nodemon์ผ๋ก ์์ํ๋ script ์ถ๊ฐ
"backend": "nodemon index.js",
|
8. Config ์ค์
mongoURI ์จ๊ธฐ๋ ์ค์ (gitignore)
9. Bcrypt ํจ์ค์๋ ์ํธํ
npm install bcrypt --save |
save ์ ์ ์ํธํ์์ผ์ค์ผํจ
(User.js์์)
saltRounds = salt๋ฅผ ์ด์ฉํด์ ๋น๋ฐ๋ฒํธ๋ฅผ ์ํธํ -> ์ํธ ์์ฑ -> ์ํธ๋ฅผ ์ด์ฉํด์ ๋น๋ฐ๋ฒํธ๋ฅผ ์ํธํ
userSchema.pre("save", function (next) {
var user = this;
// ๋น๋ฐ๋ฒํธ๋ฅผ ๋ณ๊ฒฝํ ๋๋ง
if (user.isModified("password")) {
// ๋น๋ฐ๋ฒํธ ์ํธํ
// salt ์์ฑ
bcrypt.genSalt(saltRounds, function (err, salt) {
if (err) return next(err);
//๋น๋ฐ๋ฒํธ ์์ฑ๋๋ค๋ฉด
bcrypt.hash(user.password, salt, function (err, hash) {
if (err) return next(err);
//์ํธํ ์ฑ๊ณต๋๋ฉด hash๋ ๋น๋ฐ๋ฒํธ๋ก ๋ณ๊ฒฝ
user.password = hash;
next();
});
});
}else{
next()
}
});
10. ๋ก๊ทธ์ธ
ํ ํฐ ์์ฑํ๊ธฐ ์ํ jsonwebtoken ์ค์น
npm install jsonwebtoken --save |
์ฟ ํค์ ํ ํฐ ์ ์ฅ์ํ cookie-parser ์ค์น
npm install cookie-parser --save |
๋ก๊ทธ์ธ
index.js
app.post("/api/users/login", (req, res) => {
// ์์ฒญ๋ ์ด๋ฉ์ผ์ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์๋์ง ์ฐพ๋๋ค
User.findOne({ email: req.body.email })
.then((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 });
});
});
})
.catch((err) => {
return res.status(400).send(err);
});
});
User.js
userSchema.methods.comparePassword = function (plainPassword, cb) {
// ๋น๋ฐ๋ฒํธ ๋น๊ต
bcrypt.compare(plainPassword, this.password, function (err, isMatch) {
if (err) return cb(err);
//์๋ฌ๋ ์๊ณ ๋ง์ผ๋ฉด isMatch true
cb(null, isMatch);
});
};
userSchema.methods.generateToken = function (cb) {
var user = this;
var token = jwt.sign(user._id.toHexString(), "secretToken");
user.token = token;
/*
user.save(function (err, user) {
if (err) return cb(err);
cb;
});
*/
user
.save()
.then((user) => {
cb(null, user);
})
.catch((err) => {
return cb(err);
});
};
11. Auth ๊ธฐ๋ฅ ๋ง๋ค๊ธฐ
ํ ํฐ์ ๋ง๋ ํ ์ ์ ์ ๋ณด(์๋ฒ)์ ์ฟ ํค(๋ธ๋ผ์ฐ์ )์ ๋ฃ์ด์ค
๋๊ฐ์ง ํ ํฐ์ด ์๋ก ๋ง๋์ง ์ง์์ ์ผ๋ก ์ฒดํฌ
-> ์ด๋ป๊ฒ ํ๋? ์ํฌ๋ฆฟ ํ ํฐ์ ๋ฃ์ผ๋ฉด ์ ์ ์์ด๋๊ฐ ๋์ค๋๋ฐ ๊ทธ ์์ด๋๋ฅผ db์์ ์ฐพ์์ ํด๋น ์ ์ ์ ํ ํฐ์ ํ์ธ
*get์์ฒญ ๋ฐ์ ๋ middle ware 'auth' ์ถ๊ฐ
๋ฏธ๋ค์จ์ด๋? : ์๋ํฌ์ธํธ์์ req๋ฐ์ ํ ์ฝ๋ฐฑํ์ ํ๊ธฐ์ ์ ์ค๊ฐ์์ ํด์ฃผ๋ ๊ฒ
index.js
app.get("/api/users/auth", auth, (req, res) => {
// ์ฌ๊ธฐ ์๋ค๋ ๊ฑด auth ํต๊ณผํ๋ค๋ ์๋ฏธ
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,
});
});
auth.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 });
req.token = token;
req.user = user;
next();
});
};
module.exports = { auth };
User.js
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 })
.then((user) => {
cb(null, user);
})
.catch((err) => {
return cb(err);
});
});
};
12. ๋ก๊ทธ์์ ๊ธฐ๋ฅ ๋ง๋ค๊ธฐ
๋ก๊ทธ์์ํ๋ ค๋ ์ ์ ๋ฅผ ์์ด๋๋ก ์ฐพ์์ ํด๋น ์ ์ ์ ํ ํฐ์ ์ง์์ฃผ๋ฉด๋จ
์์ด๋ ๊ฐ์ ธ์ค๋ ๋ฒ์ auth๋ฅผ ๊ฑฐ์น๊ธฐ ๋๋ฌธ์ ๋ด๊ฐ ๊ฐ์ง ๋ธ๋ผ์ฐ์ ์ฟ ํค์ ํ ํฐ์ผ๋ก ์ฐพ์ user์ ๋ณด๊ฐ req์ ๋ด๊ฒจ์ ๋์ด์ด
index.js
app.get("/api/users/logout", auth, (req, res) => {
User.findOneAndUpdate({ _id: req.user._id }, { token: "" })
.then((user) => {
return res.status(200).send({ success: true });
})
.catch((err) => {
return res.json({ success: false, err });
});
});
'๐จโ๐ป Web Development > React JS' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[React JS] 5. ํ์๊ฐ์ /๋ก๊ทธ์ธ/๋ก๊ทธ์์ ๊ธฐ๋ฅ ๊ตฌํํ๊ธฐ (0) | 2023.07.17 |
---|---|
[React JS] 4. ๋ฐฑ์๋ ๊ธฐ๋ณธ๊ตฌ์กฐ ์์ฑํ๊ธฐ (0) | 2023.07.15 |
[React JS] [์ฐธ์กฐ] Redux (0) | 2023.06.22 |
[React JS] 3. ํ๋ก ํธ์๋ ๊ธฐ๋ณธ๊ตฌ์กฐ ์์ฑํ๊ธฐ (0) | 2023.06.18 |
[React JS] 2. React.js (0) | 2023.06.08 |
์ต๊ทผ๋๊ธ