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'
);
}

}
);



//update
//@route put api/info/:id
//@desc update user interest
//@access private

router.put(
'/:id'
, authmiddle,async (req ,res ) => {
//res.send('update interest');
const {interest}=req.body;
//build a info onject
const informationFields = {};

if
(interest) informationFields.interest = interest;

try
{
let information =
await
Info.findById(req.params.id);

if
(!information)
return
res.status(404).json({msg:
'interest not found'
});

//make sure user owns interest
if
(information.user.toString() !== req.user.id){
return
res.status(401).json({msg:
'not authorized '
});
}
information =
await
Info.findByIdAndUpdate(req.params.id,
{$set: informationFields},
{new: true});
res.json(information)

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


//delete //remove
//@route delete api/info/:id
//@desc delete user interest
//@access private

router.delete(
'/:id'
,authmiddle,async (req ,res ) => {
try
{
let information =
await
Info.findById(req.params.id);
if
(!information)
return
res.status(404).json({msg:
'interest not found'
});
//make sure user owns interest
if
(information.user.toString() !== req.user.id){
return
res.status(401).json({msg:
'not authorized '
});
}
information =
await
Info.findByIdAndRemove(req.params.id);
res.json(
'deleted'
)
}
catch
(err) {
console.error(err.message);
res.status(500).send(
'Server error'
);
}
}
);

module.exports = router;
REACT-JS
Concurrently
Stop the server by
Ctrl+c in terminal

Then at root folder create a react-app
Using npx
npx create-react-app appname

Dependency’s
npm i axios react-router-dom uuid


Then
In “package.json” in ROOT
Add
Replace “reactuser” with your <app-name>

And in “package.json” in reactuser
Add an proxy so that we don’t need to send link each and every time and neglects CORS

To run
Npm run dev


You get


Now just get rid of all the unwanted files
And install
//user wish
Font from font awsome
npm install --save @fortawesome/fontawesome-free


Now you can test whether node is working or not by passing dummy data in post man

Now lets start with Authentication
For that

In reactapp under src we must create some dependency files that we need to work on authentication
Let me describe what each files does

Logintut.js
Regtut.js
Is just a frontend page where he would have integrated ton on text field etc.,
It look like it has its text box
Type checking, regex validation etc.,

Then under the return we have text input fields
So these fields only collect the data from user and will be checked by multiple source of variable to check and those data are passed into it

Want to print your doc?
This is not the way.
Try clicking the ⋯ next to your doc name or using a keyboard shortcut (
CtrlP
) instead.