I am trying to hit http://localhost:5000/api/auth/ with post request using postman but it says "cannot post api/auth".
I am using mongo db and node js server.js
server.js file:
const express = require('express');
var connectDB = require('./config/db');
const app = express();
//connect database
connectDB();
// initializing middleware
app.use(express.json({extended: false}));
app.get('/', (req,res) =>
res.json({msg:'Hellow we are here'}));
//Define Routes
app.use('api/auth', require('./routes/auth'));
app.use('/api/users', require('./routes/users'));
app.use('/api/contacts', require('./routes/contacts'));
const PORT = process.env.PORT || 5000;
app.listen(PORT, () => console.log ("server running at port 5000"));
Here is the auth file:
const express = require('express');
const router = express.Router();
const bcrypt = require('bcryptjs');
const jwt = require('jsonwebtoken');
const {check, validationResult} = require('express-validator');
const config = require('config');
const User = require('../models/User');
//#route GET api/auth
//#desc Get logged in user
//#access private
router.get('/', (req, res)=> {
res.send('Get logged in suser');
});
//#route POST api/auth
//#desc Auth user and get token
//#access public
router.post (
'/',
[
check('email', 'Please enter a valid email').isEmail(),
check('password', 'password required').exists(),
],
async (req, res)=> {
const errors = validationResult(req);
if(!errors.isEmpty()){
return res.status(400).json({errors: errors.array()});
}
const {email , password} = req.body;
try{
let user= await User.findOne({email});
console.log(user);
if(!user)
{
return res.status(400).json({msg:"Invalid credentials"});
}
const isMatch = await bcrypt.compare(password, user.password);
if(!isMatch)
{
return res.status(400).json({msg:"Invalid credentials"});
}
const payload = {
user: { id: user.id }
};
jwt.sign(payload,
config.get('jwtSecret'),
{expiresIn: 36000},
(err, token) => {
if (err)
{ throw err;}
res.send({token});
});
}
catch (err) {
console.error(err.message);
res.status(500).send('server error');
}
});
module.exports = router;
There's a missing leading slash where you define the routes. It is
//Define Routes
app.use('api/auth', require('./routes/auth'));
but it should be
//Define Routes
app.use('/api/auth', require('./routes/auth'));
Related
When I try to get data from my db I get an information "Cannot GET /api/auth/logowanie". I'm using node.js and mongodb. I've tried to solve it but nothing worked. (the port and url is in 100% correct)
My auth.js file
const router = require('express').Router();
const CryptoJs = require('crypto-js');
const User = require('../models/user');
//REJESTRACJA
router.post('/rejestracja', async (req, res)=>{
const newUser = new User({
username: req.body.username,
email: req.body.email,
password: CryptoJs.AES.encrypt(req.body.password, process.env.PASS_SEC).toString(),
});
try{
const saveduser = await newUser.save();
res.status(201).json(saveduser);
}catch(err){
res.status(500).json(err);
}
});
//LOGOWANIE
router.post('/logowanie', async (req, res) => {
try{
const user = await User.findOne({username: req.body.username});
!user && res.status(401).json("Wrong username or password")
const hashedpassword = CryptoJs.AES.decrypt(user.password, process.env.PASS_SEC);
const password = hashedpassword.toString(CryptoJs.enc.Utf8);
password !== req.body.password &&
res.status(401).json("Wrong username or password")
res.status(200).json(user);
}catch(err){ res.status(500).json(err); }
})
module.exports = router
My index.js file
const express = require('express');
const app = express();
const dotenv = require('dotenv');
dotenv.config();
const userRoute = require("./routes/user");
const authRoute = require("./routes/auth");
const mongoose = require('mongoose');
const { CLIENT_RENEG_LIMIT } = require('tls');
const { application } = require('express');
mongoose
.connect(process.env.MONGO_URL)
.then(() => console.log('Connected to Mongoose server'))
.catch((err) => {
console.log(err);
});
app.use(express.json());
app.use('/api/users', userRoute);
app.use('/api/auth', authRoute);
app.listen(process.env.PORT || 5300, ()=>{
console.log('Listening on port 5300');
});
And screenshot from Postman
Your endpoint in the auth.js file is a POST request. And you are sending a GET request from Postman.
I have my Node/Express server running. I have the main server.js file where most of the code is for the server. Now I want to separate out the routes into a separate file. I have done this before using app.use(routes). But the problem is, I want to pass a string in for one of the routes to use.
Here is my server.js code:
// other imports
import routes from './routes.js';
const app = express();
...
const port = Number.parseInt(process.env.PORT, 10) || 3001;
const serverType = process.env.NODE_ENV === 'production' ? 'Production' : 'Test';
const statusMsg = `${serverType} Node server for external facing web server on ${port}`;
// i want `routes` to have access to `statusMsg`
app.use(routes);
Then in routes.js:
import express from 'express';
const router = express.Router();
router.get('/', (req, res) => res.status(200).send(statusMsg);
export default router;
I use serverType and port elsewhere in server.js, else I would just move all that code to routes.js.
Update
Adding in updated routes.js as I understand it with suggestion from jonrsharpe.
import express from 'express';
const router = express.Router();
const createRoutes = (statusMsg) => {
router.get('/', (req, res) => res.status(200).send(statusMsg);
};
export default createRoutes;
You can separate the server logic, routes logic, and business logic (usually inside a separate file called a controller).
inside the server file try blow code:
const express = require('express');
const app = express();
const bodyParser = require('body-parser')
require('dotenv').config();
const connectDB = require('./config/config')
const cookieParser = require('cookie-parser')
const authRoutes = require('./routes/authRoutes')
const categoryRoutes = require('./routes/categoryRoutes')
const cors = require('cors');
connectDB();
app.use(bodyParser.json());
app.use(cookieParser());
app.use(cors());
//Route Mounting
app.use('/', authRoutes);
app.use('/', categoryRoutes);
app.listen(process.env.PORT, ()=>{
console.log(`Server is running on PORT: ${process.env.PORT}`)
})
Then create a separate file authRoute.js and do the following code
const express = require('express')
const { registerUser, loginUser, getAllUsers, logoutUser} = require('../controllers/authController')
const router = express.Router()
const {isAuthenticatedUser, isAuthorizedRoles} = require('../middleware/auth')
router.route('/user/new').post(registerUser);
router.route('/user/login').post(loginUser);
router.route('/users').get(getAllUsers);
router.route('/account/logout').get(logoutUser);
module.exports = router;
lastly to write the business logic create file authController.js and place the following code.
const User = require('../model/userSchema');
const bcrypt = require('bcryptjs');
const jwt = require('jsonwebtoken');
require('dotenv').config();
exports.registerUser = async (req, re, next)=>{
let password = req.body.password;
password = await bcrypt.hash(password, 10);
const newUser = req.body;
newUser.password = password;
try {
const user = await User.create(newUser);
if(user){
res.json({
success:true,
user
});
}
} catch (error) {
console.log(error);
}
}
exports.loginUser = async function(req, res){
const email = req.body.email;
const password = req.body.password;
if(!email || !password){
return res.json({
success:false,
message:'Please provide the email & Password'
})
}
const user = await User.findOne({email:email});
if(!user){
return res.json({
success:false,
message:'user with this email not found in database'
})
}
const isPasswordMatch = await bcrypt.compare(password, user.password);
if(!isPasswordMatch){
return res.json({
success:false,
message:'Your password is wrong...'
})
}
const token = jwt.sign({ _id: user._id }, process.env.JWT_SECRET, { expiresIn: process.env.JWT_EXPIRY_TIME });
res.cookie('token', token, {httpOnly:true, expires:new Date(Date.now() + 60*60*1000 )}).json({
success:true,
message:'You are logged in! Enjoy',
})
}
exports.getAllUsers = async (req, res, next)=>{
res.json({
success:true,
data:[
{
"id":1,
"name":"Yasir",
"qual":"MCS",
"age":32
},
{
"id":2,
"name":"Tabish",
"qual":"BS",
"age":21
},
{
"id":3,
"name":"Ahmed",
"qual":"BSCS",
"age":32
},
{
"id":4,
"name":"Hassan",
"qual":"MCS",
"age":33
}
]
})
}
exports.logoutUser = async (req, res, next)=>{
res.cookie('token', null, {expires:new Date(Date.now())}).json({
success:true,
message:'You are loggedOut',
})
}
This is the way you can have separation of concerns.
I'm getting error "TypeError: next is not a function" while trying to authenticate dashboard route in nodejs.
I am trying to make and CRUD app with node and mongoDB suing these modules express ejs mongoose bcryptjs passport passport-local.
Getting this error when I submit login form.
I am new in nodejs, Please help me
Thanks in advance.
auth/protect.js file
const protectRoute = (req, res, next) =>{
if (req.isAuthenticated()) {
return next();
}
console.log('Please log in to continue');
res.redirect('/login');
}
const allowIf = (req, res, next) =>{
if (!req.isAuthenticated()) {
return next();
}
res.redirect('/dashboard');
}
module.exports = {
protectRoute,
allowIf,
};
routes/login.js file
const express = require("express");
const {
registerView,
loginView,
registerUser,
loginUser,
} = require("../controllers/loginController");
const { dashboardView } = require("../controllers/dashboardController");
const { protectRoute } = require("../auth/protect");
const router = express.Router();
router.get("/register", registerView);
router.get("/login", loginView);
router.get("/", loginView);
//Dashboard
router.get("/dashboard", protectRoute, dashboardView);
router.post("/register", registerUser);
router.post("/login", loginUser);
module.exports = router;
server.js file
const express = require("express");
const cors = require("cors");
const app = express();
const mongoose = require('mongoose');
const session = require('express-session');
const passport = require("passport");
const { loginCheck } = require("./auth/passport");
var corsOptions = {
origin: "http://localhost:8081"
};
app.use(cors(corsOptions));
const db = require("./models");
db.mongoose
.connect(db.url, {
useNewUrlParser: true,
useUnifiedTopology: true
})
.then(() => {
console.log("Connected to the database!");
})
.catch(err => {
console.log("Cannot connect to the database!", err);
process.exit();
});
app.set('view engine', 'ejs');
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(session({
secret:'oneboy',
saveUninitialized: true,
resave: true
}));
app.use(passport.initialize());
app.use(passport.session());
// simple route
app.use('/', require('./routes/login'));
const PORT = process.env.PORT || 8080;
app.listen(PORT, () => {
console.log(`Server is running on port ${PORT}.`);
});
I have missed to call a function loginCheck(passport); in my server.js file that's why I was getting error during login form submission.
server.js starting code
const express = require("express");
const cors = require("cors");
const app = express();
const mongoose = require('mongoose');
const session = require('express-session');
const passport = require("passport");
//var LocalStrategy = require('passport-local').Strategy;
const { loginCheck } = require("./auth/passport");
loginCheck(passport);
........................................
I was added this function in auth/passport.js file
passport.js
//js
const bcrypt = require("bcryptjs");
LocalStrategy = require("passport-local").Strategy;
//Load model
const User = require("../models/User");
const loginCheck = passport => {
passport.use(
new LocalStrategy({ usernameField: "email" }, (email, password, done) => {
//Check customer
User.findOne({ email: email })
.then((user) => {
if (!user) {
console.log("wrong email");
return done();
}
//Match Password
bcrypt.compare(password, user.password, (error, isMatch) => {
if (error) throw error;
if (isMatch) {
return done(null, user);
} else {
console.log("Wrong password");
return done();
}
});
})
.catch((error) => console.log(error));
})
);
passport.serializeUser((user, done) => {
done(null, user.id);
});
passport.deserializeUser((id, done) => {
User.findById(id, (error, user) => {
done(error, user);
});
});
};
module.exports = {
loginCheck,
};
If you are trying to use next() in normal function then it will give an error
const allowIf = (req, res, next) =>{
return next(); // throw an error - TypeError: next is not a function
}
allowIf();
So use next() as a Callback argument to the middleware function. It will work fine in this case. Try this:
const protectRoute = (req, res, next) =>{
console.log('protectRoute');
return next();
}
app.get('/', protectRoute);
I am trying to create a register page. when I route its shows Cannot GET /api/auth/register same thing happened when I route login and others too. i use postman to throw data it's shown 5000 internet server error.
how to solve route problem for register
// tested REGISTER i used it to test this code is runing or not in tutorial this code was runnign and show in register path is "ok"
// tested REGISTER
const express = require("express");
const router = express.Router();
const User = require("../models/User");
router.get("/register", async (req, res) => {
//create new user
const user = await new User({
username:"admin",
email:"admin#gmail.com",
password: "123456"
});
//save user and respond
await user.save();
res.send("Hello")
});
module.exports = router;
index.js
const express = require("express");
const app = express();
const mongoose = require("mongoose");
const dotenv = require("dotenv");
const helmet = require("helmet");
const morgan = require("morgan");
const userRoute = require("./routes/users");
const authRoute = require("./routes/auth");
const postRoute = require("./routes/posts");
dotenv.config();
mongoose.connect(
process.env.MONGO_URL,
{ useNewUrlParser: true,
useUnifiedTopology: true
},
() => {
console.log("Connected to MongoDB");
}
);
//middleware
app.use(express.json());
app.use(helmet());
app.use(morgan("common"));
app.use("/api/auth", authRoute);
app.use("/api/users", userRoute);
app.use("/api/posts", postRoute);
app.listen(8000, () => {
console.log("Backend server is running!");
});
auth.js here the login and register file
const express = require("express");
const router = express.Router();
const User = require("../models/User");
const bcrypt = require("bcrypt");
//REGISTER
router.post("/register", async (req, res) => {
try {
//generate new password
const salt = await bcrypt.genSalt(10);
const hashedPassword = await bcrypt.hash(req.body.password,salt);
//create new user
const newUser = new User({
username: req.body.username,
email: req.body.email,
password: hashedPassword,
});
//save user and respond
const user = await newUser.save();
res.status(200).json(user);
} catch (err) {
res.status(500).json(err)
}
});
//LOGIN
router.post("/login", async (req, res) => {
try {
const user = await User.findOne({ email: req.body.email });
// make sure user is not empty {} or [];
if (!user) res.status(404).json("user not found");
const validPassword = await bcrypt.compare(req.body.password,
user.password)
// make sure password is not empty {} or [];
if(!validPassword) res.status(400).json("wrong password");
res.status(200).json(user)
} catch (err) {
res.status(500).json(err)
}
});
module.exports = router;
Been trying to get user user object by id from parameters, using User.findById and cannot access this route.
Postman response: Cannot GET /users/get/ with status 404 (not found) which is wierd.
Postman JSON response:
Unexpected '<'
Been using express-promise-router but also tried with default express.Router();
Here is my code:
routes/users.js
const express = require('express');
const router = require('express-promise-router')();
const passport = require('passport');
const router1 = express.Router();
require('../passport');
const { validateBody, schemas } = require('../helpers/routeHelpers');
const UsersController = require('../controllers/users');
const passportSignIn = passport.authenticate('local', { session: false });
const passportJWT = passport.authenticate('jwt', { session: false });
router.route('/signup')
.post(validateBody(schemas.authSchema), UsersController.signUp);
router.route('/signin')
.post(validateBody(schemas.authSchema), passportSignIn, UsersController.signIn);
router.route('/get/:id')
.get(UsersController.getUser);
router.route('/secret')
.get(passportJWT, UsersController.secret);
controllers/users
module.exports = router;
const JWT = require('jsonwebtoken');
const User = require('../models/user');
const { JWT_SECRET } = require('../configuration');
const signToken = (user) => {
return JWT.sign({
iss: 'CodeWorkr',
sub: user.id,
iat: new Date().getTime(), // current time
exp: new Date().setDate(new Date().getDate() + 1) // current time + 1 day ahead
}, JWT_SECRET);
};
module.exports = {
signUp: async (req, res) => {
const { email, password } = req.value.body;
// Check if there is a user with the same email
const foundUser = await User.findOne({ 'local.email': email });
if (foundUser) {
return res.status(403).json({ error: 'Email is already in use' });
}
// Create a new user
const newUser = new User({
method: 'local',
local: {
email: email,
password: password
}
});
await newUser.save();
// Generate the token
const token = signToken(newUser);
// Respond with token
return res.status(200).json({ token });
},
signIn: async (req, res) => {
// Generate token
const token = signToken(req.user);
res.status(200).json({ token });
},
getUser: async (req, res) => {
User.findById(req.params.id)
.then((user) => {
res.status(200).json({ user });
console.log('test');
});
},
secret: async (req, res) => {
console.log('I managed to get here!');
res.json({ secret: 'resource' });
}
};
server.js
const express = require('express');
const morgan = require('morgan');
const bodyParser = require('body-parser');
const cors = require('cors');
const mongoose = require('mongoose');
const passport = require('passport');
const db = require('./configuration/config').mongoURI;
const dbTest = require('./configuration/config').mongoURITest;
mongoose.Promise = global.Promise;
if (process.env.NODE_ENV === 'test') {
mongoose.connect(dbTest, { useMongoClient: true });
} else {
mongoose.connect(db, { useMongoClient: true });
}
const app = express();
app.use(cors());
app.use(passport.initialize());
app.use(passport.session());
// Middlewares moved morgan into if for clear tests
if (!process.env.NODE_ENV === 'test') {
app.use(morgan('dev'));
}
app.use(bodyParser.json());
// Routes
app.use('/users', require('./routes/users'));
// Start the server
const port = process.env.PORT || 3001;
app.listen(port);
console.log(`Server listening at ${port}`);
Other post routes works fine,