why is my cookie not saving in the browsers? - node.js

when i run router.post("/signin", async (req, res) from auth.js then cookie is not saving in my local host .
this is index.js
const express = require("express");
const dotenv = require("dotenv");
const mongoose = require("mongoose");
const cors = require("cors");
const { google } = require("googleapis");
const cookieParser= require('cookie-parser');
const app = express();
app.use(cors());
app.use(express.json());
const passport = require("passport");
dotenv.config({ path: "./config.env" });
const db = require("./db/connection");
app.use(require('./router/auth'));
const User= require("./UserSchema/Schma")
const messages=require("./sendMessage/message");
// messages()
// .then((e)=>{console.log(e)})
app.use(cookieParser());
app.listen(3001, (req, res) => {
console.log(`server running at port no 3001`);
});
this is auth.js
const express = require("express");
const router = express.Router();
const bcrypt = require('bcryptjs');
const jwt= require('jsonwebtoken');
const User = require("../UserSchema/Schma");
const cookieParser = require("cookie-parser");
const authenticate = require('../middleware/authenticate');
let token;
router.post("/signin", async (req, res) => {
console.log(req.body);
// res.cookie("raushan", "raushan");
try {
const { email, password } = req.body;
if (!email || !password) {
return res.json({ error: "invalid credentials you added " });
}
const details = await User.findOne({ email: email });
console.log(details);
if (!details) {
return res.json({ error: "users error" });
}
else
{
const isMatch = await bcrypt.compare(password,details.password);
console.log(isMatch);
token= await details.generateAuthToken();
console.log(token);
res.cookie("jwtoken",token,{
expiresIn:"1h",
httpOnly:true,
secure:true
}
);
if (!isMatch) {
return res.status(400).json({ error: "invalid credientials" });
} else {
return res.json({ message: "user signin successfully" });
}
}
}
catch {
console.log("something going bad");
res.status(400).json({ error: "sorry something missing" })
}
});
module.exports = router;
and this Schema.js and inside this generateAuthToken() function
const mongoose = require("mongoose");
const bcrypt = require("bcryptjs");
const jwt= require("jsonwebtoken");
const userSchema = new mongoose.Schema({
name: {
type: String,
require:true,
},
email: {
type: String,
require:true,
},
phone :{
type:Number,
require:true,
},
work:{
type:String,
require:true,
},
password:{
type:String,
require:true,
}
,
cpassword:{
type:String,
require:true,
},
tokens:[{
token:{
type:String,
require:true,
}
}]
});
userSchema.pre('save', async function(next) {
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(err);
}
}
const User = mongoose.model("USER", userSchema);
module.exports = User;
I am trying it from last two days but i can't get any solution till now please help .

It's not working because of the secure flag in auth.js:
res.cookie("jwtoken",token,{
expiresIn:"1h",
httpOnly:true,
secure:true
}
);
This is a great security practice, but it will not work on localhost because it's not over HTTPS. You need to either:
Disable the secure flag for development only, or
Enable https and use self-signed certificates for localhost development, or
Use a TLS-terminating proxy such as haproxy

Related

Experiencing an issue with the .save() function in MongoDB

I am using Node.js, Express, and MongoDB for a project and in MongoDB, .save() is not working.
index.js file code:
const express = require("express");
const app = express();
const dotenv = require("dotenv");
const helmet = require("helmet");
const morgan = require("morgan");
const mongoose = require("mongoose");
//middleware;
app.use(express.json()); //for json files;
app.use(helmet());
app.use(morgan("common"));
//routing paths;
const authUser = require("./routes/auth");
// for secrets keys;
dotenv.config();
//Connecting to Mongoose;
mongoose.connect(process.env.MONGO_PATH, {
userNewUrlParser: true, useUnifiedTopology: true
}, () => {
console.log("Connected to MongoDb");
}
)
app.use("/api/auth", authUser);
app.listen(9000, () => {
console.log("Server is Running...");
}
)
Model file name User.js:
const mongoose = require("mongoose");
const Schema = mongoose.Schema;
const UserSchema = new Schema({
username: {
type: String,
require: true,
},
password: {
type: String,
require: true,
}
});
const User= mongoose.model("User", UserSchema);
module.exports = User;
auth.js file
const router = require("express").Router();
const User = require("../models/User");
const bcrypt = require("bcrypt");
//for register;
router.get("/register", async (req, res) => {
try {
const newuser = new User({
username: "herovinay",
password: "herovinay"
});
newuser.save((err)=> {
if (err) {
res.status(500).json({ msg: "internal error is here"});
}
else {
res.status(200).json({ msg: "Data saved successfully..." });
}
});
} catch (err) {
res.send("second error is here");
}
})
module.exports = router;
When accessing localhost:9000/api/auth/register, the output is msg: "internal error is here".
Screenshot of output:
Every time I tried to hit that request, the same error came over and over again.
I tried everything and was unable to save my data to the MongoDB cluster.
Change the get method to post. to create new data in the server the post method is used. and also add the await keyword before the newuser.save(),
here is a example.
const router = require("express").Router();
const User = require("../models/User");
const bcrypt = require("bcrypt");
//for register;
router.post("/register", async (req, res) => {
try {
const newuser = new User({
username: "herovinay",
password: "herovinay"
});
await newuser.save((err)=> {
if (err) {
res.status(500).json({ msg: "internal error is here"});
}
else {
res.status(200).json({ msg: "Data saved successfully..." });
}
});
} catch (err) {
res.send("second error is here");
}
})
module.exports = router;

Mongoose: Operation `schema.findOne()` buffering timed out after 10000ms

I have a REST API made with Node.js and I use Mongoose to connect with MongoDB. Whenever I try to interact with the DB using Mongoose, I get the timeout error.
I have made sure that the DB is running and accepts connections from my IP. Using the same connection method in other projects works for some reason.
I am using mobile hotspot connection. Could that be an issue?
server.js
const express = require('express');
const app = express();
const cors = require('cors');
const userRoutes = require('../Backend/routes/userRoutes')
const taskRoutes = require('../Backend/routes/taskRoutes')
const mongoose = require('mongoose');
require('dotenv').config()
mongoose.connect(process.env.DB_CONNECTION);
app.use(cors());
app.use(express.json());
app.use(userRoutes)
app.use(taskRoutes)
app.listen(process.env.PORT || 3000 , () => {
console.log("API is now running.")
});
userRoutes.js
const userController = require('../controllers/userController')
const express = require('express');
const router = express.Router();
router.get('/users/currentUser', userController.getCurrentUserData)
router.get('/users/:userId', userController.getUserData)
router.post('/register', userController.register);
router.post('/login', userController.login);
module.exports = router;
Method in userController that causes the error (the error is caused by no matter which method I call out)
exports.login = async (req, res) => {
if (!req.body.username || !req.body.password) {
return res.status(400).send("Missing one or all required request body fields: username, password");
}
let existingUser;
try {
existingUser = await userSchema.findOne({ username: req.body.username });
} catch(err) {
return res.status(500).send("Internal server error."); //Error comes from here
}
if (!existingUser) {
return res.status(404).send('User not found');
}
const isPasswordCorrect = await bcrypt.compare(req.body.password, existingUser.password);
if (!isPasswordCorrect) {
return res.status(401).send('Invalid credentials');
}
let token;
try {
token = jwt.sign(
{ userId: existingUser._id, username: existingUser.username, tasks: existingUser.tasks},
process.env.SECRET,
{ expiresIn: "1h" }
);
} catch (err) {
console.log(err);
return res.status(500).send("Couldn't create JWT.")
}
return res.status(200).json({ token: token });
}
User model
const mongoose = require('mongoose');
const bcrypt = require('bcrypt');
const userSchema = new mongoose.Schema({
username:{
type: String,
unique: true
},
password:{
type: String
},
tasks:{
type:[mongoose.Types.ObjectId]
}
})
userSchema.pre('save', async function(next) {
const salt = await bcrypt.genSalt();
this.password = await bcrypt.hash(this.password, salt);
next();
});
module.exports = mongoose.model('user',userSchema);
.env
DB_CONNECTION="mongodb://localhost:27017/test"
SECRET='test'

GET http://localhost:3000/api/users/:userId 400 (Bad Request), Axios React

I am working on a MERN stack and I am trying to display a single user's data on its own page. The route works on the server-side in Postman, I am able to get the user by Id. But on the client-side I get a 400 bad request when trying to get the user information with axios from that route. could their be a problem with any of my endpoints?
Component
import React, { Component } from 'react';
import { Link } from 'react-router-dom'
import axios from 'axios'
import PropTypes from "prop-types";
import { connect } from "react-redux";
import Navbar from '../layouts/navbar'
// import './userDashboard.css'
class userDashboard extends Component {
state = {
user: {}
}
getUser = () =>{
const userId = this.props.match.params.userId
axios.get('/api/users/' + userId ).then(res=>{
const user = res.data;
this.setState({
user
})
}).catch((err)=> console.log(err))
}
componentDidMount() {
this.getUser()
}
render() {
const { name } = this.state.user
return (
<div>
<Navbar />
<h1 className="title-text">Hello { name }</h1>
</div>
);
}
}
userDashboard.propTypes = {
// logoutUser: PropTypes.func.isRequired,
auth: PropTypes.object.isRequired,
};
const mapStateToProps = (state) => ({
auth: state.auth,
});
export default connect(mapStateToProps)(userDashboard);
controller
router.get("/:userId", (req, res) => {
const { userId } = req.params;
if(!userId){
return res.status(400).json({message: "user id not found"})
}
if(!ObjectId.isValid(userId)){
return res.status(400).json({ message: "userId not valid"})
}
User.findById(userId,(err, user) => {
if(err) {
res.status(500);
console.log("errr 500")
} else {
if(!user)
res.status(400).json({message:"user not found"});
res.status(200).json({"user" : user})
}
})
})
server.js
const express = require("express");
const path = require('path');
const mongoose = require("mongoose");
const bodyParser = require("body-parser");
const passport = require("passport");
const app = express();
const users = require("./controllers/api/users")
app.use(
bodyParser.urlencoded({
extended: false
})
);
app.use(bodyParser.json());
app.use(express.static(`${__dirname}/client/build`));
// app.get('/*', (req, res) => {
// res.sendFile(`${__dirname}/client/build/index.html`)
// })
// app.get('/*', (req, res) => {
// res.sendFile(path.join(__dirname, '/../', 'build', 'index.html'));
// });
//DATA BASE CONFIGURATION
const dbkeys = require("./config/key").mongoURI;
mongoose.connect(
dbkeys,
{useNewUrlParser: true} )
.then(()=> console.log("database connection successful"))
.catch(err => console.log(err))
app.use(passport.initialize());
require("./config/passport")(passport);
app.use("/api/users", users);
// app.use("/api", users)
const port = 5000;
app.listen( port, () => console.log("server us up and running on port 5000!"))
Schema
const mongoose = require("mongoose");
const Schema = mongoose.Schema;
const ClassworkSchema = new Schema({
name: String,
time: Date,
todo: String,
isDone: false
});
const OutcomesSchema = new Schema({
name: String,
time: Date,
todo: String,
isDone: false,
isApproved: false
})
const MeetupSchema = new Schema({
name: String,
time: Date,
location: String,
attended: false
})
const UserSchema = new Schema({
name: {
type: String,
required: true
},
email: {
type: String,
required: true
},
password: {
type: String,
required: true
},
date: {
type: Date,
default: Date.now
},
classwork:{type: [ClassworkSchema], default: []},
outcomes: [OutcomesSchema],
meetups: [MeetupSchema],
});
// const User = mongoose.model('users', UserSchema);
// const Classwork = mongoose.model('Classwork', ClassworkSchema );
// module.exports = {
// User : User ,
// // Classwork : Classwork
// }
module.exports = mongoose.model("users", UserSchema);
You need to include the server side localhost endpoint in your GET request from the client side.
getUser = () =>{
const userId = this.props.match.params.id;
axios.get(`http://localhost:5000/api/users/${userId}`).then(res=>{
const user = res.data;
this.setState({
user
})
}).catch((err)=> console.log(err))
}
You are requesting a response from the server side , so it is required to include the correct path to which the response should travel.
You will need to include this path in all of the requests you send from the client side to the server side. I recommend using a proxy in the client side package.json as below,
"proxy":"http://localhost:5000"
This will let you write your endpoint path as you have done in your GET request implementation.
For the CORS error,
Install CORS in your server side package.json as npm install cors
Then import CORS to your server.js as const cors = require('cors');
Then use CORS as middleware app.use(cors());

OverwriteModelError: Cannot overwrite `user` model once compiled

I am facing this issue. I looked online for hours to find out what the problem is before posting here. I keep getting this error OverwriteModelError: Cannot overwrite ``user`` model once compiled. after sending a post request via postman and I can't find out what's going on. could you help me find out what's going on? thank you so much in advance!
server.js
const express = require("express");
const app = express();
const user = require("./routes/user");
const connectDB = require("./config/db");
connectDB();
app.use(express.json({extended: false}));
app.get("/", (req, res) => {
res.send("welcome to our api");
});
app.use("/user", user);
const PORT = 3000 || process.env.PORT;
app.listen(PORT, () => {
console.log(`PORT ${PORT} listening and refeshing...`);
});
db.js
const mongoose = require("mongoose");
const connectDB = () =>
mongoose
.connect(
"some database",
{
useNewUrlParser: true,
useUnifiedTopology: true,
}
)
.then(
() => {
console.log("mongoDB conneted");
},
(err) => {
console.log(err);
}
);
module.exports = connectDB;
user.js
const express = require("express");
const router = express.Router();
const mongoose = require("mongoose");
const bcrypt = require("bcrypt");
const jwt = require("jsonwebtoken");
const {body, validationResult} = require("express-validator");
router.get("/", (req, res) => {
res.send("hello");
});
router.post(
"/",
[
// password must be at least 5 chars long
body("email").isEmail(),
body("password").not().isEmpty(),
],
async (req, res) => {
const errors = validationResult(req);
if (!errors.isEmpty) {
return res.status(400).json({errors: errors.array()});
}
try {
const UsersSchema = mongoose.Schema({
email: {type: String, required: true},
password: {type: String, required: true},
});
var users = mongoose.model("user", UsersSchema);
var user = new users({
email: req.body.email,
password: req.body.password,
});
const salt = await bcrypt.genSalt(10);
user.password = await bcrypt.hash(req.body.password, salt);
user.save((err, user1) => {
if (err) {
console.log("error posing user");
throw err;
}
});
console.log(user.id);
const payload = {
user: {
id: user.id,
},
};
} catch (error) {
console.log(error);
res.status(400);
}
}
);
module.exports = router;
Every time the route runs it tries to create a schema which is already created.Mongoose create the collection with the first argument user by converting it to plural i.e. users.

User.find() returns empty response in mongodb express

I'm working with nextjs and express .I'm implementing simple signin form.I'm sending user credential and using find() ,checking whether user exist or not.but find() returns empty response.
In terminal find() returns array of that record.
model
const mongoose = require('mongoose')
const schema = mongoose.Schema
const user = new schema({
username: { type: String} ,
password: { type: String},
role: { type: String},
})
module.exports = mongoose.model('user', user);
router.js
const express = require('express')
const router = express.Router()
const user = require('../models/user');
router.post('/user/signin', (req, res) => {
user.find({
username: req.body.username, password: req.body.password
}, (err, user) => {
console.log(user);
if (err) {
result.status(404).send({ error: 'There is some error' });
} else if (user.length == 1) {
var token = 'kkl';//token
res.send({ token });
} else {
console.log(err);
res.send('Incorrect Email and Password');
}
});
})
module.exports = router;
this.is my index.js
const express = require('express')
const next = require('next')
const bodyParser = require('body-parser')
const PORT = process.env.PORT || 4000
const dev = process.env.NODE_DEV !== 'production' //true false
const nextApp = next({ dev })
const handle = nextApp.getRequestHandler() //part of next config
const mongoose = require('mongoose')
const router = express.Router();
nextApp.prepare().then(() => {
const app = express();
const db = mongoose.connect('mongodb://localhost:27017/knowledgeBase')
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
app.use('/knowledgeBase', require('./routes/router'));
app.get('*', (req, res) => {
return handle(req, res) // for all the react stuff
})
app.listen(PORT, err => {
if (err) {
console.log(err);
throw err;
}
console.log(`ready at http://localhost:${PORT}`)
})
})
please help
What response you get when you try this?
According to the response I will edit response.
router.post("/user/signin", async (req, res) => {
if (!req.body.username) return res.status(400).send("username cannot be null");
if (!req.body.password) return res.status(400).send("Password cannot be null");
const user = await User.findOne({ username: req.body.username});
if (!user) return res.status(400).send("User not found");
if (req.body.password!== user.password)
return res.status(400).send("Invalid password.");
res.send("logined");
});

Resources