I am sending a post request to my Heroku API, but receiving nothing in return.
This is where I am making the request:
const [ user, setUser] = useState({
email:"",
password:""
})
const handleChange = e => {
const { name, value } = e.target
setUser({
...user,
[name]: value
})
}
const login = () => {
axios.post("https://<myherokuapp>/login", user)
.then(res => {
alert(res.data.message)
setLoginUser(res.data.user)
navigate("/")
})
}
This is the body of the request:
app.post("/login", (req, res)=> {
const { email, password} = req.body
User.findOne({ email: email}, (err, user) => {
if(user){
if(password === user.password ) {
res.send({message: "Login Successfull", user: user})
} else {
res.send({ message: "Password didn't match"})
}
} else {
res.send({message: "User not registered"})
}
})
})
app.post("/register", (req, res)=> {
const { name, email, password} = req.body
User.findOne({email: email}, (err, user) => {
if(user){
res.send({message: "User already registerd"})
} else {
const user = new User({
name,
email,
password
})
user.save(err => {
if(err) {
res.send(err)
} else {
res.send( { message: "Successfully Registered, Please login now." })
}
})
}
})
})
This is the index.js running on heroku:
import express from "express"
import cors from "cors"
import mongoose from "mongoose"
const app = express();
const port = process.env.PORT || 9002;
app.use(express.json())
app.use(express.urlencoded())
app.use(cors())
mongoose.connect("mongodb+srv://<myDbLink>.mongodb.net/?retryWrites=true&w=majority", {
useNewUrlParser: true,
useUnifiedTopology: true
}, () => {
console.log("DB connected")
})
const userSchema = new mongoose.Schema({
name: String,
email: String,
password: String
})
const User = new mongoose.model("User", userSchema)
//Routes
app.post("/login", (req, res)=> {
const { email, password} = req.body
User.findOne({ email: email}, (err, user) => {
if(user){
if(password === user.password ) {
res.send({message: "Login Successfull", user: user})
} else {
res.send({ message: "Password didn't match"})
}
} else {
res.send({message: "User not registered"})
}
})
})
app.post("/register", (req, res)=> {
const { name, email, password} = req.body
User.findOne({email: email}, (err, user) => {
if(user){
res.send({message: "User already registerd"})
} else {
const user = new User({
name,
email,
password
})
user.save(err => {
if(err) {
res.send(err)
} else {
res.send( { message: "Successfully Registered, Please login now." })
}
})
}
})
})
app.get("/",(req,res)=>{
res.send("get is working")
})
app.listen(port,() => {
console.log("BE started at port")
})
When I tried in my localhost , it was working fine , but now it is giving me an error user is not registered , even when I have the user in my database. Please help me solve this problem , this is the first time I am using heroku with nodejs.
Your route code is correct but the approach of hosting a website on Heroku is wrong, you should need to connect DB with Atlas Cluster for more detail and follow up on the official documentation Host Website on Heroku that uses Mongodb
Related
a user login successfully and redirected to profile was implemented with success.but, when i try to access a new route by requesting http://localhost:5000/user/admin/request/newAdmin route the authentication middleware responses with You are not authorized to view this page after login why is that???
server.js
require("dotenv").config();
const express = require("express");
const app = express();
// const flash = require("connect-flash");
const session = require("express-session");
const passport = require("passport");
const mongoose = require("mongoose");
const MongoStore = require("connect-mongo");
const cors = require("cors");
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
app.use(cors());
// app.use(flash());
app.use(
session({
secret: process.env.SESSION_SECRET,
resave: true,
saveUninitialized: true,
store: MongoStore.create({
mongoUrl: process.env.DB,
collection: "sessions",
}),
cookie: { secure: false, maxAge: 1000 * 60 * 60 * 24 * 3 },
})
);
app.use(passport.initialize());
app.use(passport.session());
mongoose
.connect(process.env.DB)
.then(() => {
console.log("DB connection successful");
})
.catch((err) => {
console.log(`DB connection Error: ${err}`);
});
const userRouter = require("./routes/userRoutes");
app.use("/user", userRouter);
const PORT = process.env.PORT || 5000;
app.listen(PORT, () => {
console.log(`server is running on port ${PORT}`);
});
module.exports = app;
userRoutes.js
const router = require("express").Router();
const passport = require("passport");
const { ObjectID } = require("mongodb");
const LocalStrategy = require("passport-local");
const bcrypt = require("bcrypt");
const crypto = require("crypto");
const Token = require("../models/token");
const sendEmail = require("../utils/sendEmail");
const User = require("../models/userModel.js");
router.route("/register").post(
(req, res, next) => {
User.findOne({ fullName: req.body.fullName }, (err, user) => {
if (err) {
next(err);
} else if (user) {
res.json({ user: "user with that name already exists!" });
} else {
const {
fullName,
email,
userType,
department,
stream,
id,
batch,
phoneNumber,
password,
} = req.body;
const hash = bcrypt.hashSync(password, 12);
console.log(hash);
if(userType === "Admin"){
User.find({ userType: "Admin" }, (err, users) => {
if (err) console.log(err);
if(users.length === 0 ){
const newUser = new User({
fullName,
email,
userType,
department,
stream,
id,
batch,
phoneNumber,
password: hash,
});
newUser.save((err, data) => {
if (err) console.log(err);
next(null, data);
});
}else{
const newUser = new User({
fullName,
email,
userType,
department,
stream,
id,
batch,
phoneNumber,
password: hash,
approved: false
});
newUser.save((err, data) => {
if (err) console.log(err);
next(null, data);
})
}
})
}else{
const newUser = new User({
fullName,
email,
userType,
department,
stream,
id,
batch,
phoneNumber,
password: hash,
});
newUser.save((err, data) => {
if (err) console.log(err);
next(null, data);
});
}
}
});
},
passport.authenticate("local", { failureRedirect: "/" }),
(req, res, next) => {
const userAuth = req.user.fullName;
if (userAuth) {
User.findOne({ fullName: userAuth }, (err, user) => {
if (err) console.log(err);
const userPriv = user.userType;
if(userPriv === "Student"){
return res.json({ user: user.fullName ,identity: {id: "Student"}});
}
else if(userPriv === "Admin"){
if(user.approved){
return res.json({ user: user.fullName , identity: {id: "Admin",approved: true} });
}
return res.json({ user: user.fullName , identity: {id: "Admin",approved: false} });
}else{
return res.json({ user: user.fullName , identity: {id: "Teacher"} });
}
});
} else {
res.sendStatus(401).json({ user: "Incorrect password or email" });
}
}
);
router.route("/login").post(passport.authenticate("local"), (req, res) => {
const userAuth = req.user.fullName;
console.log(req.user);
if (userAuth) {
User.findOne({ fullName: userAuth }, (err, user) => {
if (err) console.log(err);
const userPriv = user.userType;
if(userPriv === "Student"){
return res.json({ user: user.fullName ,identity: {id: "Student"}});
}
else if(userPriv === "Admin"){
if(user.approved){
return res.json({ user: user.fullName , identity: {id: "Admin",approved: true} });
}
return res.json({ user: user.fullName , identity: {id: "Admin",approved: false} });
}else{
return res.json({ user: user.fullName , identity: {id: "Teacher"} });
}
});
} else {
res.sendStatus(401).json({ user: "Incorrect password or email" });
}
});
router.route("/admin/request/newAdmin").get(ensureAuthenticated,(req, res) => {
User.find({userType: "Admin", approved: false},(err,users) => {
if (err) console.log(err);
res.json({users});
})
});
router.route("/logout").get((req, res, next) => {
req.logout(function (err) {
if (err) {
return next(err);
}
console.log("the user has logged out!");
res.json({ user: "logout success!" });
});
});
passport.serializeUser((user, done) => {
done(null, user._id);
});
passport.deserializeUser((id, done) => {
User.findOne({ _id: new ObjectID(id) }, (err, doc) => {
done(null, doc);
});
});
const customFields = {
usernameField: "email",
};
passport.use(
new LocalStrategy(customFields, (email, password, done) => {
User.findOne({ email }, (err, user) => {
console.log(`User ${user.email} attempted to log in.`);
if (err) return done(err);
if (!user) return done(null, false);
if (!bcrypt.compareSync(password, user.password)) {
return done(null, false);
}
return done(null, user);
});
})
);
function ensureAuthenticated(req, res, next) {
if (req.isAuthenticated()) {
return next();
}
console.log(req.isAuthenticated());
console.log(req.user);
res.redirect("/user/err");
}
router.route("/err").get((req,res) => {
res.status(401).json({ msg: "You are not authorized to view this page" });
})
module.exports = router;
i was expecting for the ensureAuthenticated middleware to respond with authenticated because the user is logged in.but one thing i noticed is when i console logged req.user in the login route it set it to the current user object but in the ensureAuthenticated middleware it is undefined even if the user has not logged out.why is that?may be am i wrong when initializing the session and passport in server.js?
I am working on ReactJs and NodeJS and I am creating a signup page. I post data to server but it is always pending.
Which part did I do wrong? It would be nice if someone can help.
Front end:
const handleSubmit = (event) => {
// prevent page refresh
event.preventDefault();
const newUserData = {
name: name,
email: email,
password: password,
};
axios
.post("/signup", newUserData)
.then((res) => {
console.log(res.data);
})
.catch((error) => {
console.log(error);
});
setEmail("");
setName("");
setPassword("")
console.log("form submitted ✅");
};
Backend:
router.post("/signup", (req, res) => {
const { name, email, password } = req.body;
if (!email || !password || !name) {
res.status(422).send({ error: "Please add all the fields" });
}
console.log(req.body);
User.findOne({ email: email })
.then((savedUser) => {
if (savedUser) {
res.status(422).send({ error: "Email already been used" });
}
bcrypt.hash(password, 12).then((hashedpassword) => {
const user = new User({
name,
email,
password: hashedpassword,
});
user
.save()
.then((user) => {
res.json({ message: "Sign Up Successfully" });
})
.catch((err) => {
console.log(err);
});
});
})
.catch((err) => {
console.log(err);
});
});
in package.json i set proxy as
"proxy": "http://localhost:5000",
I guess you are using MongoDB as well, in that case keep in your mind that the findOne is async, so you need to use await before. And for to save data you need to use the .create() method from MongoDB, e.g.
router.post("/signup", async (req, res) => {
const { name, email, password } = req.body;
if (!email || !password || !name) {
res.status(422).send({ error: "Please add all the fields" });
}
console.log(req.body);
await User.findOne({ email: email })
.then((savedUser) => {
if (savedUser) {
// you need to add return to stop the code
return res.status(422).send({ error: "Email already been used" });
}
// or you can add else because the code keep running
bcrypt.hash(password, 12).then((hashedpassword) => {
const user = await User.create({
name,
email,
password: hashedpassword,
});
user
.save()
.then((user) => {
res.json({ message: "Sign Up Successfully" });
})
.catch((err) => {
console.log(err);
});
});
})
.catch((err) => {
console.log(err);
});
});
I think it is better to use something like throw new Error('Email already been used') instead of return for your res.status(422).send({ error: "Email already been used" }); because if you have return the server doesn't give back an error, but a normal answer, but of course it is ok if you want that.
I want you to be sure that before you submit, the values name, email, password, are updated. Please try:
const handleSubmit = async (event) => {
// prevent page refresh
event.preventDefault();
console.log(`The value for the name: ${name}`);
console.log(`The value for the email: ${email}`);
console.log(`The value for the password: ${password}`);
try {
const response = await axios.post("http://localhost:5000/signup", {
name,
email,
password,
});
console.log(response.data);
setEmail("");
setName("");
setPassword("");
console.log("form submitted ✅");
} catch (error) {
console.log(error);
}
};
I have a function to check if a user exists, and a function to create a new user in my User model.
What I want to do is call them in the router to check if a user with the email adress in req.body already exists.
If it does, I want to return a message, and if not, I want to create the user.
When I try to call the route in Postman, I get this error in node console :
node_modules/express/lib/response.js:257
var escape = app.get('json escape')
TypeError: Cannot read properties of undefined (reading 'get')
User model :
const Sequelize = require("sequelize");
const connexion = require("../database");
const User = connexion.define(
"users",
{
id: {
type: Sequelize.INTEGER,
autoIncrement: true,
allowNull: false,
primaryKey: true,
},
email: {
type: Sequelize.STRING(100),
allowNull: false,
},
password: {
type: Sequelize.STRING(100),
allowNull: false,
},
},
{
freezeTableName: true
}
);
function checkUser(userEmail) {
const findUser = User.findOne({ where: { userEmail } }).catch((err) => {
console.log(err);
});
if (findUser) {
return res.json({ message: "Cette adresse email est déjà enregistrée" });
} else {
return false;
}
}
function createUser(userData) {
console.log(userData);
User.create(userData)
.then((user) => {
console.log(user);
})
.catch((err) => {
console.log(err);
});
}
module.exports = { createUser, checkUser };
user controller :
const createUser = require("../models/User");
const bcrypt = require("bcrypt");
const saltRounds = 10;
addUser = async (req, res) => {
try {
const userData = req.body;
console.log(req.body);
bcrypt.hash(userData.password, saltRounds, async function (err, hash) {
userData.password = hash;
const newUser = await createUser(req.body);
res.status(201).json({ newUser });
});
} catch (err) {
console.log(err);
res.status(500).json("Server error");
}
};
module.exports = addUser;
user router :
const express = require("express");
const router = express.Router();
const addUser = require("../controllers/userController");
const { checkUser } = require("../models/User");
router.post("/", async (req, res) => {
const { email } = req.body;
const alreadyExists = await checkUser(email);
if (!alreadyExists) {
addUser(req.body);
}
});
module.exports = router;
EDIT : Finally I'm trying a more simple way. I will do the check part directly into the createUser function.
But now, it creates the user even if the email already exists ^^
async function createUser(userData) {
console.log(userData);
const findUser = await User.findOne({ where: userData.email }).catch(
(err) => {
console.log(err);
}
);
findUser
? console.log(findUser)
: User.create(userData)
.then((user) => {
console.log(user);
})
.catch((err) => {
console.log(err);
});
}
i think the problem is with this part you are trying to use res but it doesn't exist in your checkUser function
if (findUser) {
return res.json({ message: "Cette adresse email est déjà enregistrée" });
} else {
return false;
}
try this instead
if (findUser) {
return true });
} else {
return false;
}
UPDATE to fix the problem of user creation if it already exists
async function createUser(userData) {
console.log(userData);
const findUser = await User.findOne({ where: userData.email }).catch(
(err) => {
console.log(err);
}
);
if(!findUser){
findUser
? console.log(findUser)
: User.create(userData)
.then((user) => {
console.log(user);
})
.catch((err) => {
console.log(err);
});
}
}
Problem solved by doing this (thanks super sub for your help):
async function createUser(userData) {
console.log(userData);
const email = userData.email;
const findUser = await User.findOne({ where: { email } }).catch((err) => {
console.log(err);
});
if (!findUser) {
User.create(userData)
.then((user) => {
console.log(user);
})
.catch((err) => {
console.log(err);
});
}
}
I am trying to authenticate the user using jwt and found this error. This is a MERN project and I had to verify the user whose data I have stored in MongoDb before showing a secret page.
Other errors which VSCode is highlighting are:
1.When I hover on ._id (authentication.js)
const rootUser=await User.findOne({_id:verifyToken._id,"tokens.token":token})
Property '_id' does not exist on type 'string | JwtPayload'.
2.When I hover on req.rootUser(app.js)
res.send(req.rootUser)
Property 'rootUser' does not exist on type 'Request<{}, any, any, ParsedQs, Record<string, any>>
My code looks as follows:
app.js
const mongoose = require('mongoose')
const dotenv = require('dotenv')
const bcrypt = require('bcryptjs')
const jwt=require('jsonwebtoken')
const app = express()
const router = express.Router();
const port = 5000
const authenticate=require("./middleware/authenticate")
dotenv.config({ path: './config.env' })
const DB = process.env.DATABASE;
app.use(express.json());
const User = require('./model/userSchema')
mongoose
.connect(DB, {
useUnifiedTopology: true,
useNewUrlParser: true,
})
.then(() => console.log('Database connected.'))
.catch(err => console.log(err));
app.get('/', (req, res) => {
res.send('Hello World!')
console.log("hey")
})
app.post('/register', async (req, res) => {
const { name, email, work, phone, password, cpassword } = req.body;
if (!name || !email || !work || !phone || !password || !cpassword) {
return res.status(422).json({ error: "Form Not Properly Filled" });
}
try {
const userExist = await User.findOne({ email: email })
if (userExist) {
return res.status(422).json({ error: "Email ALready Exists" })
}
else if (password != cpassword) {
return res.status(422).json({ error: "Password does not match" })
}
else {
const user = new User({ name, email, work, phone, password, cpassword })
await user.save()
res.status(201).json({ message: "user registered successfully" })
}
} catch (error) {
console.log(error);
}
})
//login route
app.post('/signin', async (req, res) => {
try {
let token;
const { email, password } = req.body;
if (!email || !password) {
return res.status(400).json({ error: "Please fill the data correctly" })
}
const userLogin = await User.findOne({ email: email })
console.log(userLogin);
if (userLogin) {
const isMatch = await bcrypt.compare(password, userLogin.password)
token = await userLogin.generateAuthToken();
console.log(token)
res.cookie("jwtoken",token,{
expires:new Date(Date.now()+25892000000),
httpOnly:true
})
if (!isMatch) {
res.status(400).json({ error: "Invalid Credentials" })
}
else {
res.status(200).json({ message: "Login Success" })
}
}
else {
res.status(400).json({ error: "Invalid Credentials" })
}
} catch (error) {
console.log(error)
}
})
//about page request
app.get('/about',authenticate, (req, res) => {
console.log("About")
res.send(req.rootUser)
})
app.get('/forget', (req, res) => {
res.cookie("harsh","test")
res.send('Forget World!')
})
app.listen(port, () => {
console.log(`Example app listening at http://localhost:${port}`)
})
authenticate.js
const User=require("../model/userSchema")
const Authenticate=async (req,res,next)=>{
try {
console.log(req.cookies)
const token=req.cookies.jwtoken;
console.log("below")
const verifyToken =jwt.verify(token,process.env.SECRET_KEY)
console.log(verifyToken)
const rootUser=await User.findOne({_id:verifyToken._id,"tokens.token":token})
if(!rootUser){
throw new Error("User Not Found")
}
req.token=token;
req.rootUser=rootUser;
req.userID=rootUser._id;
next();
} catch (error) {
res.status(401).send('Unauthorized : No token provided')
console.log(error)
}
}
module.exports=Authenticate;
userSchema.js
const mongoose=require('mongoose')
const bcrypt=require('bcryptjs')
const jwt=require('jsonwebtoken')
const userSchema=new mongoose.Schema({
name:{
type:String,
required:true,
},
email:{
type:String,
required:true,
},
phone:{
type:String,
required:true,
},
work:{
type:String,
required:true,
},
password:{
type:String,
required:true,
},
cpassword:{
type:String,
required:true,
},
tokens:[
{
token:{
type:String,
required:true,
}
}
]
})
userSchema.pre('save' , async function(next){
console.log("inside hash")
if(this.isModified('password')){
this.password=await bcrypt.hash(this.password,12)
this.cpassword=await bcrypt.hash(this.cpassword,12)
}
next();
})
userSchema.methods.generateAuthToken = async function(){
try {
let token =jwt.sign({_id:this._id},process.env.SECRET_KEY)
this.tokens=this.tokens.concat({token : token})
await this.save();
return token
} catch (error) {
console.log(error)
}
}
const User=mongoose.model('USER',userSchema);
module.exports=User;
1. GENERATE JWT TOKEN WHEN USER LOGIN
Generate Token and Send this token with a response...
router.post("/login", async (req, res) => {
try {
// checking username
const user = await User.findOne({ email: req.body.email });
!user && res.status(401).json("Wrong Username");
// checking password
const bytes = CryptoJS.AES.decrypt(user.password, process.env.SECRET_KEY);
const originalPassword = bytes.toString(CryptoJS.enc.Utf8);
// If password not match return respond
originalPassword !== req.body.password &&
res.status(401).json("Wrong Password");
// Creating Json Web Token
const accessToken = jwt.sign(
{ id: user._id, isAdmin: user.isAdmin },
process.env.SECRET_KEY,
{ expiresIn: "5d" }
);
// stop sending password to respond
const { password, ...info } = user._doc;
// Returning User(info) , also sending accessToken
res.status(200).json({ ...info, accessToken });
} catch (err) {
res.status(500).json(err);
}
});
2. VERIFY TOKEN MIDDLEWARE
Create this verify token function use as a MIDDLEWARE in your routes...
const jwt = require("jsonwebtoken");
function verify(req, res, next) {
const authHeader = req.headers.token;
if (authHeader) {
const token = authHeader.split(" ")[1];
jwt.verify(token, process.env.SECRET_KEY, (err, user) => {
if (err) res.status(403).json("Token is not valid");
req.user = user;
next();
});
} else {
return res.status(402).json("You are not authorized");
}
}
module.exports = verify;
3. VERIFY-IN ROUTES AS AN MIDDLEWARE
const verify = require("../verifyToken");
// CREATE
router.post("/", verify, async (req, res) => {
if (req.user.isAdmin) {
const newList = new List(req.body);
try {
const savedList = await newList.save();
res.status(201).json(savedList);
} catch (error) {
res.status(500).json(err);
}
} else {
res.status(403).json("You are not allowed!");
}
});
// DELETE
router.delete("/:id", verify, async (req, res) => {
if (req.user.isAdmin) {
try {
await List.findByIdAndDelete(req.params.id);
res.status(201).json("The list has been deleted");
} catch (err) {
res.status(500).json(err);
}
} else {
res.status(403).json("You are not allowed!");
}
});
CONCLUSION:-
Create a token with jwt.sign when user login...
Create a verify function in the root directory export this function...
Require this function in routes file use as a middleware...
I have a project with the below Model, Controller, and Route File for user. I am wanting to implement sequelize, which I have managed to partially achieve using the account files below, however, I am struggling to work out how to implement logging in and ensuring a request has a valid token usijng user.ensureToken which would become account.ensureToken.
I'm fairly new to Node.Js so I'm not even sure where to start
user.model.js
const bcrypt = require('bcrypt');
const sql = require("./db.js");
const HashBits = require("../config/auth.config.js");
const faker = require('faker');
// constructor
const User = function(user) {
this.first_name = user.first_name;
this.last_name = user.last_name;
this.mob_no = user.mob_no;
this.user_name = user.user_name;
this.password = user.password;
};
User.create = (newUser, result) => {
bcrypt.hash(newUser.password, HashBits.saltRounds, (err, hash) => {
newUser.password = hash;
sql.query("INSERT INTO users SET ?", newUser, (err, res) => {
if (err) {
// console.log("error: ", err);
result(err, null);
return;
}
newID = res.insertId;
// console.log("created user: ", { id: res.insertId, ...newUser });
result(null, { id: res.insertId, ...newUser });
});
});
};
User.authenticate = (user,result) => {
// sql.query(`SELECT * FROM customers WHERE id = ${customerId}`, (err, res) => {
sql.query(`SELECT * FROM users WHERE user_name = '${user.user_name}'`, (err, res) => {
// sql.query("SELECT * FROM users ", (err, res) => {
if (err) {
// console.log("error: ", err);
result(err, null);
return;
}
if(res.length !== 1){
// console.log("error: found multiple users");
result("error: found multiple users", null);
return;
}
// console.log("Found user: ",res[0]);
bcrypt.compare(user.password, res[0].password, function(err, res2) {
if(res2){
// console.log("Yes");
result(null,res[0]);
}else{
// console.log("On ya bike");
result("ERROR",null);
// return;
}
});
});
};
module.exports = User;
user.controller.js
const User = require("../models/user.model.js");
var jwt = require("jsonwebtoken");
const config = require("../config/auth.config.js");
// Create and Save a new User
exports.create = (req, res) => {
// Validate request
if (!req.body) {
res.status(400).send({
message: "Content can not be empty!"
});
}
// Create a User
const user = new User({
first_name: req.body.first_name,
last_name: req.body.last_name,
mob_no: req.body.mob_no,
user_name: req.body.user_name,
password: req.body.password
});
// Save User in the database
User.create(user, (err, data) => {
if (err)
res.status(500).send({
message:
err.message || "Some error occurred while creating the User."
});
else res.send(data);
});
};
exports.authenticate = (req,res) => {
if (!req.body) {
res.status(400).send({
message: "Content can not be empty!"
});
}
const user = new User({
user_name: req.body.user_name,
password: req.body.password
});
User.authenticate(user, (err,data) => {
if(err)
res.status(500).send({
message:
err.message || "Some error occurred while authenticating the User."
});
else {
var token = jwt.sign({ id: user.id }, config.secret, {
expiresIn: 86400 // 24 hours
});
// res.send(data);
res.status(200).send({
id: data.id,
username: data.user_name,
accessToken: token
});
}
});
};
exports.ensureToken = (req, res, next) => {
let token = req.headers["x-access-token"];
if (!token) {
return res.status(403).send({
message: "No token provided!"
});
}
jwt.verify(token, config.secret, (err, decoded) => {
if (err) {
return res.status(401).send({
message: "Unauthorized!"
});
}
req.userId = decoded.id;
next();
});
}
user.routes.js
module.exports = app => {
const users = require("../controllers/user.controller.js");
// Create a new User
app.post("/User", users.create);
// Login
app.post("/User/Login", users.authenticate);
};
account.model.js
const bcrypt = require("bcrypt");
module.exports = (sequelize, Sequelize) => {
const Account = sequelize.define("account", {
firstName: {
type: Sequelize.STRING
},
username: {
type: Sequelize.STRING
},
password: {
type: Sequelize.STRING,
set(value){
const hash = bcrypt.hashSync(value, 10);
this.setDataValue('password', hash);
}
}
});
return Account;
};
account.controller.js
const db = require("../models");
const Account = db.accounts;
const Op = db.Sequelize.Op;
var jwt = require("jsonwebtoken");
const config = require("../config/auth.config.js");
// Create and Save a new New
exports.create = (req, res) => {
// Validate request
if (!req.body.username) {
res.status(400).send({
message: "Content can not be empty!"
});
return;
}
// Create a Site
const account = {
firstName: req.body.firstName,
username: req.body.username,
password: req.body.password
};
Account.create(account)
.then(data => {
res.send(data);
})
.catch(err => {
res.status(500).send({
message:
err.message || "Some error occurred while creating the Account."
});
});
};
exports.authenticate = (req,res) => {
if (!req.body) {
res.status(400).send({
message: "Content can not be empty!"
});
}
const account = new Account({
username: req.body.username,
password: req.body.password
});
};
account.routes.js
module.exports = app => {
const accounts = require("../controllers/account.controller.js");
var router = require("express").Router();
app.post("/account", accounts.create);
app.post("/account/Login", accounts.authenticate);
};
you need to use jwt token for access token as you said and you are bcrypt password in model file which will be security issue you have to bcrypt password as soon as it comes in request I have implemented it in my answer remove code of password bcrypt from your model file
you have to import in your account.controller.js
const db = require("../models");
const User = db.user;
require('dotenv').config();
const Op = db.Sequelize.Op;
const errors = require('../config/errors');
const error = errors.errors;
var jwt = require("jsonwebtoken");
var bcrypt = require("bcryptjs");
module.exports = {
signup: async (req, res) => {
if (!req.body.first_name|| !req.body.lastt_name || !req.body.password) {
return res.status(200).send(error.MANDATORY_FIELDS);
}
try {
// Save User to Database
User.create({
name: req.body.name,
email: req.body.email,
mo_no: req.body.mo_no,
city: req.body.city,
password: bcrypt.hashSync(req.body.password, 8),
user_type: "admin"
}).then(function (user) {
return res.status(200).send(error.OK)
})
.catch(function (err) {
console.log(err);
return res.status(500).send(error.SERVER_ERROR)
});
} catch (e) {
console.log(e);
return res.status(500).send(error.SERVER_ERROR)
}
},
signin: async (req, res) => {
if (!req.body.email || !req.body.password) {
return res.status(200).send(error.MANDATORY_FIELDS);
}
User.findOne({
where: {
email: req.body.email
}
}).then(function (user) {
if (!user) {
return res.status(404).send(error.USER_NOT_PRESENT);
}
const passwordIsValid = bcrypt.compareSync(
req.body.password,
user.password
);
if (!passwordIsValid) {
return res.status(422).send(error.PASSWORD_MISSMATCH, {
accessToken: null
});
}
const token = jwt.sign({ id: user.id, first_name: user.first_name },
process.env.secret, {
expiresIn: 86400 // 24 hours
});
const authorities = [];
return res.status(200).send({
id: user.id,
name: user.name,
email: user.email,
accessToken: token
});
});
})
.catch(function (err) {
console.log(err)
return res.status(500).send(error.SERVER_ERROR);
});
}
}
than you have to create a separate folder for authorization like authorize.js or authJwt.js where you have to check is token is valid or not put this code in authorize.js
at decoding time secret token or password also needed which you have in .env file
const jwt = require("jsonwebtoken");
verifyToken = (req, res, next) => {
let token = req.headers["x-access-token"];
if (!token) {
return res.status(403).send(error.TOKEN_NOT_PROVIDED);
}
jwt.verify(token, process.env.secret, (err, decoded) => {
if (err) {
return res.status(401).send(error.UNAUTHORIZED);
}
req.first_name= decoded.first_name;
req.id = decoded.user_id
next();
});
};
const authJwt = {
verifyToken: verifyToken
};
module.exports = authJwt;
than you have to import authorize.js file in your routes whenever you want like this
const authorize = require('../authorize.js');
module.exports = app => {
const accounts = require("../controllers/account.controller.js");
var router = require("express").Router();
app.post("/account", accounts.create);
app.post("/account/Login",
authorize.verifyToken,accounts.authenticate);
};
it will be more effective if you genreate access token at signin time