Share
Explore

MERN -Saran

KS
Killer Space
MERN
@author-saran

//for package.json
1.npm init -y

//for dependency
2.npm i bcrypt nodemon express-validator config express mongoose jsonwebtoken

"dependencies": {
"bcryptjs": "^2.4.3",
"config": "^3.3.1",
"express": "^4.17.1",
"express-validator": "^6.4.0",
"jsonwebtoken": "^8.5.1",
"mongoose": "^5.9.11"
}


3. npm i -D nodemon concurrently

4. Change scripts to
"scripts": {
"start": "node server.js",
"server":"nodemon server.js"
}

from “text”:”text/error@/..etc,”

5. Create a file “server.js” in root

6. In server.js
Type this code
const express = require('express');

const app = express();

const PORT = process.env.PORT || 5000;

app.listen(PORT,() => console.log(`server started on port ${PORT}`))




7. Now try to run
(Cli code) Npm run server

o/p

8. To test API working
Use an req & res in server.js to check via postman , browser etc.,
const express = require('express');

const app = express();

app.get('/',(req , res ) =>
res.json({msg:'hi'})
);

const PORT = process.env.PORT || 5000;

app.listen(PORT,() => console.log(`server started on port ${PORT}`))


o/p
//success

9. Create some js files and define a routes fo that js in server.js
“reg.js”
const express = require('express');
const router = express.Router();

//@route post api/reg
//@desc signup user
//@access Public

router.post('/', (req ,res ) => {
res.send('Reg a user');
}
);
module.exports = router
Create some js file
Most important
“Module.exports” is mandatory

These js files have code logic & import these files in “server.js”
Like “server.js”
const express = require('express');

const app = express();

app.get('/',(req , res ) =>
res.json({msg:'hi'})
);

//define routes
app.use('/api/reg', require('./routes/reg'));
app.use('/api/auth', require('./routes/auth'));
app.use('/api/info', require('./routes/info'));

const PORT = process.env.PORT || 5000;

app.listen(PORT,() => console.log(`server started on port ${PORT}`))

o/p

10. Connection of data base
Create a cluster in mongodb
Add username and password

And copy its shareable link

Now create a config folder in root
And create 2 files
Db.js
Default.json


Default.json
Has mongoURI that you have already copied from mongo
Database name is “TEST”
// type user password and username

Db.js
Has a a code for connecting with mongoDB with URI


11.Then create a models in a Model folder with required model files
To hold use those variables in db,frontend etc.,

12. Create a model name with UPPERCASE
Connect with mongoose
Then have variables
REGISTRATION FORM IN NODEJS & MONGOOSE
Then export it with a name
I.e., in
“Reg.js” in models

const mongoose = require('mongoose');

const UserSchema = mongoose.Schema({
name: {
type : String,
required: true
},

email: {
type : String,
required: true,
unique:true
},

password: {
type : String,
required: true
},
date: {
type : Date,
default: Date.now
}

});


module.exports = mongoose.model('reg',UserSchema);
Collection name is “reg” but it stores as regs since mongoDB and mongoose stores in plural



For using those exported data from models in route
Import it from models
And to send req with param

“Reg.js” in routes
router.post('/', (req ,res ) => {
//to send req
res.send(req.body);
}
);



To accept data in “server.js” init a middleware

//init middleware //for accepting data req
app.use(express.json({extended: false}));



Now to send it to api
Refactor “reg.js”

Don't forget to import express validator to validate the input on serverside

In headers add content-type & application/json
Now pass data in body

o/p
If all they are validated

13.sending data to mongodb

POST http://localhost:5000/api/reg

This stores data in reg collection

14. Async and await??

15. jwt.io
16.user must get a jwt token from server once data has been saved in DB in order to check/get it back
17. Jwt has 3 parts
Header
Payload
Signature

18.user will get a token from any of these for future purpose to “login”
19.responses must be an jwt token
In order to get that

In reg.js we must change the response into upcoming code
a)

Also must import some files from db.js for jwtSecret and config



b)


And default.json must use an key
c)

o/p
20.So final docs look like
“reg.js” in routes
const express = require('express');

const router = express.Router();

//for bcrypt
const bcrypt = require('bcryptjs');

//jwt
const jwt = require('jsonwebtoken');

//to use jwtSecret
const config = require('config');

//for validation
const { check, validationResult } = require('express-validator');


const Reg = require('../models/Reg')

//@route post api/reg
//@desc signup user
//@access Public

router.post('/', [//validation
check('name','name is req').not().isEmpty(),
check('email','its not a valid').isEmail(),
check('password','its not a more than 8 char').isLength({min:8})
],
async (req ,res ) => {

const errors = validationResult(req);

if(!errors.isEmpty()){
return res.status(400).json({errors: errors.array()})
}
//to send req
//res.send('passed');
const{name , email , password} = req.body;
try{
//check for exisitng userr
let user = await Reg.findOne({email: email});
if(user){
return res.status(400).json({msg:'user exist'});

}
//creates a new instance in db incase if() fails
user = new Reg({
name,
email,
password
});

//hash password
const salt = await bcrypt.genSalt(10);

user.password = await bcrypt.hash(password , salt);

//save it db
await user.save();


//1 res as your saved
//1 res.send('usersaved')

// 2 response as jwt token
const payload = {
user:{
id: user.id
}
}

//to generate a token //4params //1.payload //2.token must be in a config
jwt.sign(payload,config.get('jwtSecret'),{
//3.options
expiresIn: 360000
},//4.callback
(err,token)=>{
if(err) throw err;
res.json({ token });
});


}catch{
console.log(err.message);
res.status(500).send('server error');
}

}
);
module.exports = router


21.Reg.js in model remains same
22.server.js remains same
23.default.js remains same as 19.(c)


LOGIN / AUTHENTICATION

24. We will be doing 2 work in authenticating
1.just authenticate user exist or not and get token
2. Is exist we will match the token and get the id

In “auth.js” in routes it must configured with same set of rules for validatoin of email & password
Then generation on token must be done in same as “reg.js”


So we must include same set of files from “reg.js”



















For validation

For generation of token

o/p

To note we haven’t included case sensitivity in email

24.
2.)
If user is validated then we must get user specific details
For that we need a middleware to a access the token from header and verify it
If token is verified
User id can be decoded from the token
Since token has id and other data with it in an encoded form
So token is decoded to get token and
That token is passed to
“auth.js” in routes and fetch its data using the id it got from middle ware


First create a folder named “middle ware“ in root
In that folder create a file named
“authmiddle.js”
Which is a middle ware for our “auth.js”
In “authmiddle.js”


25 since it is a middle ware function we must include all the dependencies

Since it is a middle ware it has a 3rd parameter to next route

Token is collected from header using (x-auth-token) which is key to token

If there is no token then it is rejected
If there is token
The token is verified and decoded to get the data in it
From that decoded token we can get user “id”
The decoded data is assigned to user i.e req.user
And those data are passed to next() route which is
“auth.js” in routes

So
“Autthmiddle.js” looks like
//function tht has access to req n res obj
//to check token in header


//jwt
const jwt = require('jsonwebtoken');

//to use jwtSecret
const config = require('config');

//middleware function
//has 3 params //1.req // 2.res //3.next to move to next route
module.exports = function(req,res,next){
//get token from header
// key to the token //x-auth-token//protected route
const token = req.header('x-auth-token');

//check if not a token
if(!token){
return res.status(401).json({msg:'no token,denied'});
}
try {
//once verified obj to be posted in decoded

const decoded = jwt.verify(token, config.get('jwtSecret'));

//assign payload to req.user that moves to next
req.user = decoded.user;
next();
} catch (err) {
return res.status(401).json({msg:' token not valid,denied'});
}
}

And “auth.js” in routes
We import “authmiddle.js”
And use an parameter for authmiddle function to call middle ware
Then it looks like
So overall auth.js looks like
const express = require('express');
const router = express.Router();

//for bcrypt
const bcrypt = require('bcryptjs');

//jwt
const jwt = require('jsonwebtoken');

//to use jwtSecret
const config = require('config');

//bring middleware authmiddle.js
const authmiddle = require('../middleware/authmiddle');

//for validation
const { check, validationResult } = require('express-validator');

//Reg models to access its data model and collection name
const Reg = require('../models/Reg')
//@route get api/auth
//@desc get logged user
//@access private

//authmiddle is a function call()
router.get('/',authmiddle ,async (req ,res ) => {
try {
//(+password) for inc password
//(-password) for except password
//(password) for only password
const user = await Reg.findById(req.user.id).select('-password');
res.json(user);
} catch (err) {
console.error(err.message);
res.status(500).send('server error');
}
}
);
//@route post api/auth
//@desc auth user & get token
//@access Public

router.post('/',[
//validation
check('email','its not a valid').isEmail(),
check('password','pass do not exixt').exists()
], async (req ,res ) => {
//response
//res.send('log in user');
const errors = validationResult(req);

if(!errors.isEmpty()){
return res.status(400).json({errors: errors.array()});
}
const{email,password} = req.body;
try {
//check whether email exist or not
//in regreact collection in database
//Reg refers to Reg.js (models)
let user = await Reg.findOne({email: email});
if(!user){
return res.status(400).json({msg:'invalid user'});
}
//if email exist check for password is same or not
const isMatch = await bcrypt.compare(password, user.password);
if(!isMatch){
return res.status(400).json({msg:'invalid pass/password'});
}
const payload = {
user:{
id: user.id
}
}
//to generate a token //4params //1.payload //2.token must be in a config
jwt.sign(payload,config.get('jwtSecret'),{
//3.options
expiresIn: 3600
},//4.callback
(err,token)=>{
if(err) throw err;
res.json({ token });
});
} catch (err) {
console.error(err.message);
res.status(500).send('server error');
}});
module.exports = router;

o/p
Authentication and token gen

POST http://localhost:5000/api/auth

Copy that token and paste it
Header as key & value

GET http://localhost:5000/api/auth




CRUD

Get all users those are logged in with their data
These must be done in “info.js” in route page
o/p

Insert user interest


It checks whether there is interest is valid or not
If it is valid then those interest are checked / validated against authorization
If it is valid then it is stored in interest collection
Update and Delete by id
Frst the user is checked whether he is valid or not if he is not authorized his req will be denied
In update only his interest fields are being updated
In delete his interest collection is getting deleted


In update it checks whether the user is authorized and also check whether interest is present or not
If in case there is no interest field it will create new one

o/p
For delete it is same as update it deletes its complete collection
When it wants to delete it by _id
o/p

So final code look like
//4 routes since CRUD

const express = require('express');
const router = express.Router();


//for validation
const { check, validationResult } = require('express-validator');

//bring middleware authmiddle.js
const authmiddle = require('../middleware/authmiddle');

const Reg = require('../models/Reg');
const Info = require('../models/Info');


//getall
//@route get api/info
//@desc get all user interest
//@access private

router.get('/', authmiddle, async (req ,res ) => {
try {
const information = await Info.find({user: req.user.id}).sort({date:-1});
res.json(information);
} catch (err) {
console.error(err.message);
res.status(500).send('server error');
}
}
);

//create
//@route post api/info
//@desc add new user interest
//@access private

router.post('/', [authmiddle,[
check('interest','interest is req').not().isEmpty()
]],async (req ,res ) => {
const errors = validationResult(req);

if(!errors.isEmpty()){
return res.status(400).json({errors: errors.array()});
}

const {interest}=req.body;

try {
const newInfo = new Info({
interest,
user: req.user.id
});


const information = await newInfo.save();

res.json(information);
} catch (err) {
console.error(err.message);
res.status(500).send('server error');
}

}