Error: Unknown authentication strategy "local" while trying to signin - javascript

I have been building this project from a tutorial. The signup functionality works fine but the login feature doesn't work. Whenever I try logging in a registered user using postman the error I get is
Error: Unknown authentication strategy "local"
In the other posts on stack overflow, I didn't find a solution to this error. Passport, passport-local and passport-jwt are all installed so that shouldn't be the issue. I would really appreciate any sort of help.
passport.js
require('dotenv').config();
const passport = require('passport');
const LocalStrategy = require('passport-local').Strategy;
const JWTStrategy = require('passport-jwt').Strategy;
const User = require('./models/User');
// Environment variables
const STRATEGY_KEY = process.env.STRATEGY_KEY;
const cookieExtractor = req => {
let token = null;
// Retrieve the token from cookies
if (req && req.cookies) {
token = req.cookies['access_token'];
}
return token;
};
const jwtOptions = {
jwtFromRequest: cookieExtractor,
secretOrKey: STRATEGY_KEY,
};
// Authorization for protected routes
passport.use(
new JWTStrategy(jwtOptions, (payload, done) => {
User.findById({ _id: payload.sub }, (err, user) => {
// Check for error
if (err) return done(err, false);
// Check if user exists
if (user) return done(null, user);
return done(null, false);
});
})
);
// Local strategy using username and password
passport.use(
new LocalStrategy((username, password, done) => {
User.findOne({ username }, (err, user) => {
// Error while fetching the user from database
if (err) return done(err);
// No such user exists
if (!user) return done(null, false);
// Check if entered password matches
user.comparePassword(password, done);
});
})
);
routes.js
require('dotenv').config();
const express = require('express');
const passport = require('passport');
const router = express.Router();
const STRATEGY_KEY = process.env.STRATEGY_KEY;
const signToken = userID => {
return jwt.sign(
{
iss: STRATEGY_KEY,
sub: userID,
},
STRATEGY_KEY,
{
expiresIn: '1h',
}
);
};
router.post(
'/signin',
passport.authenticate('local', { session: false }),
(req, res) => {
if (req.isAuthenticated()) {
const { _id, username, email } = req.user;
const token = signToken(_id);
res.cookie('access_token', token, {
httpOnly: true,
sameSite: true,
});
res.status(200).json({
isAuthenticated: true,
user: {
username,
email,
},
});
}
}
);
module.exports = router;

So after many hours of debugging, the solution I found to this problem was that I didn't import passport.js file in routes.js file, which I was not expecting since that import stays there ideal not doing anything, not being part of any code(exceot the import) but I was wrong. The passport configuration we make in that file is imported under the hood even though it doesn't take part in any further lines of that file.

Related

User is not authenticated jswtoken

I have created a login page and a about page the user will only access the about page if the user is logged in.
I am trying to authenticate the user by using the tokens generated while signing in, but the token is not getting authenticated even after signing in with the correct credentials. I don't know what is the problem?
This is code to my sign-in and token generating method
const express = require("express");
const { default: mongoose } = require("mongoose");
const router = express.Router();
const bcrypt = require("bcrypt");
const jwt = require("jsonwebtoken");
require("../db/conn");
const User = require("../model/userSchema");
const cookieParser = require('cookie-parser');
const Authenticate = require("../middleware/authenticate");
router.use(cookieParser());
//LOgin route
router.post("/signin", (req, res)=>{
if(!req.body.email || !req.body.password){
return res.status(400).json({error: "Plz fill the required data"});
}else{
bcrypt.hash(req.body.password, 12, function (err, hash) {
User.findOne({email: req.body.email}, function (err, foundUser) {
if(err){
console.log(err);
}else{
if(foundUser){
bcrypt.compare(req.body.password, foundUser.password, function (err, result) {
if(result){
return res.json({message: "successfully log in"})
}else{
return res.json({message: "incorrect password"});
}
});
const email = req.body.email;
const token = jwt.sign(
{ user_id: foundUser._id, email },
process.env.TOKEN_KEY,
{
expiresIn: "720h",
}
);
foundUser.tokens = foundUser.tokens.concat({token: token});
foundUser.save();
// res.status(200).json(foundUser);
console.log(foundUser);
}else{
return res.status(400).json({message: "user not found"});
};
}
})
})
}
});
//about us page
router.get("/about", Authenticate, function (req, res) {
console.log("about running");
res.send(req.rootUser);
});
module.exports = router;
this is the code to authenticate the user
require("dotenv").config({path: "./config.env"});
const jwt = require("jsonwebtoken");
const User = require("../model/userSchema");
const Authenticate = async(req, res, next) =>{
try {
const token = req.cookies.jwtoken;
const verifyToken = jwt.verify(token, process.env.TOKEN_KEY);
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 (err) {
console.log(err);
return res.status(401).send("Unauthorized: No token provided");
}
}
module.exports = Authenticate;
This is react based code of: About-page to display it or not based on user's authenticity.
const navigate = useNavigate();
const callAboutPage = async() =>{
try {
const res = await fetch("/about",{
method: "GET",
headers: {
Accept: "application/json",
"Content-Type" : "application/json"
},
credentials: "include"
});
const data = await res.json();
console.log(data);
if(!res.status === 200){
const error = new Error(res.error);
throw error;
}
} catch (err) {
console.log(err);
navigate("/login");
}
}
As said in the comment looks like there is a issue on the process for setting up the jwtoken, and when you sign in, you just need to find the user and compare the password, there is no need to do the hash with Bcrypt, since you're not registing new user, for example, i will use Async/await instead of callback function, in order for you to read it much more easier:
//Login route
router.post("/signin", async (req, res)=> {
const { reqEmail, reqPassword } = req.body; //destructuring so less thing to write at the next step
if(!reqEmail || !reqPassword) {
return res.status(400).json({message: "Plz fill the required data"});
}
try {
const foundUser = await User.findOne({email: reqEmail})
if(!foundUser) {
return res.status(400).json({message: "Wrong username or password!"})
}
const result = await bcrypt.compare(reqPassword, foundUser.password);
if(!result){
return res.json({message: "Wrong username or password!"})
} else {
const accessToken = jwt.sign(
{ user_id: foundUser._id, email: foundUser.email},
process.env.TOKEN_KEY,
{ expiresIn: "720h",}
);
// I am confuse what are you trying to do here, in your place I would set up on the cookie since you do that on your authentification.
res.cookie("jwt", accessToken, {
maxAge: 60000, // 60 sec for testing
httpOnly: true,
sameSite: false, //false only for dev
secure: false, //false only for dev
})
res.status(200).json(foundUser);
};
} catch (error) {
return res.status(500).json({message: `${error}`})
}
Than the authentification middleware :
// ...
const Authenticate = (req, res, next) => {
const accessToken = req.cookies.jwt
if(!accessToken) {
return res.status(401).json({error: "Unauthorized: No token provided"});
}
try {
const user = jwt.verify(accessToken, process.env.TOKEN_KEY)
if(user) {
req.user = user
return next();
}
} catch (error) {
return res.status(403).json({error: "Forbidden token error"})
}
}
about page component it's simple for now since you don't manage any state
const navigate = useNavigate();
const callAboutPage = async() =>{
try {
const res = await fetch("/about",{
headers: {
"Content-Type": "application/json"
},
credentials: "include"
});
if(res.status === 200){
const data = await res.json();
// set up the state for rendering
console.log(data);
} else {
// you can also create a state to catch the error message from the backend, in this case the response json should be move to above the if statement.
throw new Error("You must log in to get access")
// than you can display this error message, or from the backend using state for this bloc, and the catch bloc
// navigate to /login
}
} catch (err) {
console.log(err);
navigate("/login");
}
}
router.use(cookieParser());
Try to use cookieParser with app.use instead. (app from express instense)
Expample:
const app = express();
app.use(cookieParser());
and try to put it before server listening in index.js or app.js file.
Hope it help.

"Cannot set headers after they are sent to the client" for private routes after logging in JWT NodeJS

I am working on a backend for a Online mediconsult app and I came across this error in the JWT authentication. Since I am a newbie I dunno much about this topic. I have this 3 routes on my NodeJS /register, /login, /appointments. I was able to hit "/register" and "/login" perfectly fine. But when I copy the JWT token generated by "/login" route and paste it 'authorization' header it throws the problem.
node:internal/errors:484
ErrorCaptureStackTrace(err);
^
Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client
at new NodeError (node:internal/errors:393:5)
at ServerResponse.setHeader (node:_http_outgoing:644:11)
at ServerResponse.header (C:\Users\krish\Desktop\mrcooper-task\server\node_modules\express\lib\response.js:794:10)
at ServerResponse.send (C:\Users\krish\Desktop\mrcooper-task\server\node_modules\express\lib\response.js:174:12)
at module.exports.login (C:\Users\krish\Desktop\mrcooper-task\server\controllers\authController.js:62:7) {
code: 'ERR_HTTP_HEADERS_SENT'
}
Node.js v18.12.0
A strange thing is, when I restart the server again with the same auth token, it works!.
Wonder why would it hit the above error before restarting ?
Code
index.js
const express = require("express");
const cors = require("cors");
const mongoose = require("mongoose");
const app = express();
require('dotenv').config();
//External routes
const authRoutes = require("./routes/authRoutes");
const appointRoutes = require("./routes/appointRoutes");
// Middlewares
app.use(cors());
app.use(express.json());
//DB connection
const dbURI =
process.env.DB_URL;
mongoose
.connect(dbURI, { useNewUrlParser: true, useUnifiedTopology: true })
.then((result) =>
app.listen(8080, () =>
console.log("App sucessfully started on localhost port 8080")
)
)
.catch((err) => console.log(err));
//Internal routes
app.use(authRoutes);
app.use(appointRoutes);
appointRoutes.js
const { Router } = require("express");
const verify = require("./verifyToken")
const router = Router();
router.get("/appointments",verify, (req, res) => {
res.send({ message: "Appointment route" });
});
module.exports = router;
authRoutes.js
const { Router } = require("express");
const User = require("../models/User");
const bcrypt = require("bcryptjs");
const jwt = require("jsonwebtoken");
const { registerValidator, loginValidator } = require("../validation");
const router = Router();
router.post("/register", async (req, res) => {
//Validate data before creating a user
const { error } = registerValidator(req.body);
if (error) {
return res.status(400).send(error.details[0].message);
}
//Check if email already exists
const emailExists = await User.findOne({ email: req.body.email });
if (emailExists) {
return res.status(400).send("Email already exists");
}
const { name, email, password, catogery, DOB } = req.body;
//Hash password
const salt = await bcrypt.genSalt(10);
const hashedPassword = await bcrypt.hash(password, salt);
//console.log(hashedPassword);
try {
const user = await User.create({
name,
email,
password: hashedPassword,
catogery,
DOB,
});
res.status(201).json({ user: user._id });
} catch (err) {
//console.log(err);
res.status(400).send(err);
}
});
router.post("/login", async (req, res) => {
const { email, password } = req.body;
//Validate data before authenticating a user
const { error } = loginValidator(req.body);
if (error) {
return res.status(400).send(error.details[0].message);
}
//Check if email dosen't exists
const user = await User.findOne({ email: req.body.email });
if (!user) {
return res
.status(400)
.send("Email dosen't exists. Please register and try again");
}
//Passowrd is incorrect
const validPassword = await bcrypt.compare(password, user.password);
if (!validPassword) return res.status(400).send("Invalid Passowrd");
//Create and assign JWT token
const token = jwt.sign({_id: user._id}, process.env.TOKEN_SECRET)
res.header('auth-token', token).send(token);
//console.log(email, password);
res.send("Logged In!");
});
module.exports = router;
Here's what I did
I did few googles and searches on this error and found out that this error mainly throws out when we return multiple response per cycle. I checked the code below and I did'nt see multiple response coming from neither /login route nor /appointments route. Would there be any response leaks from if conditions accidentaly?
When I exit from nodemon and start again with the same take generated, now it can hit the /appointment. I wonder how it works ?
You get error when function like this
if(statement){
res.send(something)
}
res.send(something)
because code is continue after res.send() function
You must fix it to
if(statement){
return res.send(something)
}
return res.send(something)
and your res.send function in authController.js:62:7

Cannot read properties of undefined (reading 'id') error JWT(Json Web Token)

Created MongoDb User Schema
MongoDb User
const mongoose = require("mongoose"); // Import mongoose
const UserSchema = new mongoose.Schema( // Create User Schema
{
username: { type: String, required: true, unique: true },
email: { type: String, required: true, unique: true },
password: { type: String, required: true },
isAdmin: {
type: Boolean,
default: false,
},
},
{ timestamps: true } // Add timestamps
);
module.exports = mongoose.model("User", UserSchema); // Export User Model
Used express.js Routes files in user.js
user.js
const User = require("../models/User"); // Import User Model Schema
const {
verifyTokenAndAuthorization
} = require("./verifyToken"); // Import verifyTokenAndAuthorization
const router = require("express").Router(); // Import express Router
//UPDATE
router.put("/:id", verifyTokenAndAuthorization, async (req, res) => {
if (req.body.password) {
req.body.password = CryptoJS.AES.encrypt( // Encrypt password
req.body.password, // Password
process.env.PASS_SEC // Encrypt password with secret key
).toString();
}
try {
const updatedUser = await User.findByIdAndUpdate( // Find user by id and update
req.params.id, // Find user by id
{
$set: req.body, // Set user data
},
{ new: true } // Return updated user
);
res.status(200).json(updatedUser); // Return user
} catch (err) { // Catch error
res.status(500).json(err); // Return error
}
});
module.exports = router;
Routes files in auth.js added access token
Access Token
const router = require('express').Router(); // import express
const User = require('../models/User'); // import user model
const CryptoJS = require('crypto-js'); // import crypto-js
const jwt = require('jsonwebtoken'); // import jsonwebtoken
//REGİSTER
router.post('/register', async (req, res) => {
const newUser = new User({
username: req.body.username, // username
email: req.body.email, // req.body.email is the same as req.body.email
password: CryptoJS.AES.encrypt(req.body.password,process.env.PAS_SEC).toString(), // encrypt password
}) // create new user
try{
const savedUser = await newUser.save(); // save user
res.status(201).json(savedUser); // send user
} catch(err){
res.status(500).json({message: err}); // send error
}
});
//LOGIN
router.post("/login", async (req, res) => {
try{
const user = await User.findOne({username: req.body.username}); // find user
if(!user){ // if user is not found
return res.status(400).json({message: "User not found"}); // send error
}
const hashedPassword = CryptoJS.AES.decrypt(user.password,process.env.PAS_SEC); // decrypt password
const Originalpassword = hashedPassword.toString(CryptoJS.enc.Utf8); // convert to string
const {password,...others} = user._doc; // others is the user data without password // Güvenlik için password olmadan kullanıcıyı aktardık ve ._doc ise mongodb datamızı document içinden gösteriyor
const accessToken = jwt.sign({ // create access token
userId: user._id, // user id
isAdmin: user.isAdmin // isAdmin
},
process.env.JWT_SEC, // secret key
{expiresIn: "24h"} // expire time
);
if(Originalpassword !== req.body.password){ // if password is not correct
return res.status(401).json({message: "Incorrect password"}); // send error
} else{
res.status(200).json({...others,accessToken}); // send success
}
}catch(err){ // if error
res.status(500).json({message: err}); // send error
}
});
module.exports = router; // export router
Routes files in verifyToken.js
VerifyToken.js
const jwt = require("jsonwebtoken"); // Import jsonwebtoken
const verifyToken = (req, res, next) => { // Verify token
const authHeader = req.headers.token; // Get token from header
if (authHeader) { // If token exists
const token = authHeader.split(" ")[1]; // Get token from header
jwt.verify(token, process.env.JWT_SEC, (err, user) => { // Verify token
if (err) res.status(403).json("Token is not valid!"); // Return error
req.user = user; // Set user
next(); // Call next middleware
});
} else {
return res.status(401).json("You are not authenticated!"); // Return error
}
};
const verifyTokenAndAuthorization = (req, res, next) => { // Verify token and authorization
verifyToken(req, res, () => {
if (req.user.id === req.params.id || req.user.isAdmin) { // If user id is equal to id from url or user is admin
next(); // Call next middleware
} else {
res.status(403).json("You are not alowed to do that!"); // Return error
}
});
};
module.exports = {
verifyToken, // Export verifyToken
verifyTokenAndAuthorization, // Export verifyTokenAndAuthorization
};
I used Postman. All the queries are working, but when I want to update the user, postman also gives an error. How can ı fix this error is : Cannot read properties of undefined (reading 'id') error. i cant see where i went wrong pls hep mee
Postman Error is
You have to send the JWT token that you get in the response of your login call to the request to update the user.

GET information from user in database

I am making full stack app and learn from tutorials and videos . I have a problem with GET request to get information about user which is login in the system. I use Postman to check the requests. When I add user with /login , the Postman look user's accesstoken code. I copy his code and paste it in authorization key in headers in Postman and when I change the URL in localhost to /infor to get information about this user and send it. But it say me "Invalid Authentication". I can't find the wrong. I think the problem is in controllers/userCtrl.js in getUser function. Can you help me?
I put the code:
server.js
require('dotenv').config()
const express = require('express')
const mongoose = require('mongoose')
const cors = require('cors')
const fileUpload = require('express-fileupload')
const cookieParser = require('cookie-parser')
const app = express()
app.use(express.json())
app.use(cookieParser())
app.use(cors())
// Use temp files instead of memory for managing the upload process.
app.use(fileUpload({
useTempFiles: true
}))
// Routes
app.use('/user', require('./routes/userRouter'))
// Connect to Mongodb
const URL = process.env.MONGO_URL
mongoose.connect(URL,{
useCreateIndex: true,
useFindAndModify: false,
useNewUrlParser: true,
useUnifiedTopology: true
}, err =>{
if(err) throw err;
console.log('Connected to MongoDB')
})
const PORT = process.env.PORT || 5000
app.listen(PORT, () => {
console.log('Server is running on port', PORT)
})
.env
MONGO_URL = ***********
ACCESS_TOKEN_SECRET = ***********
REFRESH_TOKEN_SECRET = *************
routes/userRouter.js
require('dotenv').config()
const express = require('express')
const mongoose = require('mongoose')
const cors = require('cors')
const fileUpload = require('express-fileupload')
const cookieParser = require('cookie-parser')
const app = express()
app.use(express.json())
app.use(cookieParser())
app.use(cors())
// Use temp files instead of memory for managing the upload process.
app.use(fileUpload({
useTempFiles: true
}))
// Routes
app.use('/user', require('./routes/userRouter'))
// Connect to Mongodb
const URL = process.env.MONGO_URL
mongoose.connect(URL,{
useCreateIndex: true,
useFindAndModify: false,
useNewUrlParser: true,
useUnifiedTopology: true
}, err =>{
if(err) throw err;
console.log('Connected to MongoDB')
})
const PORT = process.env.PORT || 5000
app.listen(PORT, () => {
console.log('Server is running on port', PORT)
})
models/userModel.js
const mongoose = require('mongoose')
const userSchema = new mongoose.Schema({
name: {
type: String,
required: true,
trim: true
},
email: {
type: String,
required: true,
unique: true
},
password: {
type: String,
required: true,
},
role: {
type: Number,
default: 0
},
cart: {
type: Array,
default: []
}
}, {
timestamps: true
})
module.exports = mongoose.model('Users', userSchema)
middleware/auth.js
const jwt = require('jsonwebtoken')
const auth = (req, res, next) => {
try{
const token = req.header("Authorization")
if(!token) return res.status(400).json({ msg: "Invalid Authentication" })
jwt.verify(token, process.env.ACCESS_TOKEN_SECRET, (err, user) => {
if(!err) return res.status(400).json({msg: "Invalid Authentication" })
req.user = user
next()
})
} catch (err) {
return res.status(500).json({msg: err.message})
}
}
module.exports = auth
controllers/userCtrl.js
const Users = require('../models/userModel')
const bcrypt = require('bcrypt')
const jwt = require('jsonwebtoken')
const userCtrl = {
register: async (req, res) => { // async before a function means one simple thing: a function always returns a promise.
try{
const { name, email, password } = req.body
const user = await Users.findOne({ email }) // wait until the promise resolves
if(user) return res.status(400).json({msg: "The email already exists"})
if(password.length < 6)
return res.status(400).json({msg: "Password is at least 6 characteres long."})
//Password encryption
const passwordHash = await bcrypt.hash(password, 10)
const newUser = new Users({
name, email, password: passwordHash
})
// save mongodb
await newUser.save()
//then create jsonwebtoken to authentication
const accesstoken = createAccessToken({ id: newUser._id })
const refreshtoken = createRefreshToken({ id: newUser._id })
res.cookie('refreshtoken', refreshtoken, {
httpOnly: true,
path: '/user/refresh_token'
});
res.json({accesstoken})
} catch(err){
return res.status(500).json({msg: err.message})
}
},
login: async (req, res) => {
try{
const {email, password} = req.body;
const user = await Users.findOne({email})
if(!user) return res.status(400).json({msg: "User does not exist."})
const isMatch = await bcrypt.compare(password, user.password)
if(!isMatch) return res.status(400).json({msg: "Incorrect password"})
// if login success, create access token and refresh token
const accesstoken = createAccessToken({ id: user._id })
const refreshtoken = createRefreshToken({ id: user._id })
res.cookie('refreshtoken', refreshtoken, {
httpOnly: true,
path: '/user/refresh_token'
});
res.json({accesstoken})
} catch(err){
return res.status(500).json({msg: err.message})
}
},
logout: async (req, res)=> {
try{
res.clearCookie('refreshtoken', {path: '/user/refresh_token'})
return res.json({msg: "Logged out"})
}catch(err){
return res.status(500).json({msg: err.message})
}
},
refreshToken: (req, res) => {
try{
const rftoken = req.cookies.refreshtoken
if(!rftoken) return res.status(400).json({msg: "Please login or Register"})
jwt.verify(rftoken, process.env.REFRESH_TOKEN_SECRET, (err, user) => {
if(err) return res.status(400).json({msg: "Please login or Register"})
const accesstoken = createAccessToken({id: user.id})
res.json({ accesstoken })
})
}catch (err) {
return res.status(500).json({msg: err.message})
}
},
getUser: async (req, res) => { // problem
try{
const user = await (await Users.findById(req.user.id)).isSelected('-password')
if(!user) return res.status(400).json({ msg: "Useer does not exist."})
res.json(req.user)
}catch (err) {
return res.status(500).json({msg: err.message})
}
}
}
const createAccessToken = (user) => {
return jwt.sign(user, process.env.ACCESS_TOKEN_SECRET, { expiresIn: '1d' })
}
const createRefreshToken = (user) => {
return jwt.sign(user, process.env.REFRESH_TOKEN_SECRET, { expiresIn: '7d' })
}
module.exports = userCtrl
For your middle ware for getting the token (auth function)
const { authorization } = req.headers
if (!authorization) {
console.log('[No Authorization Code]');
return res.status(401).send({ message: 'Unauthorized' });
}
if (!authorization.startsWith('Bearer')) {
console.log('[Authorization need to start with Bearer]')
return res.status(401).send({ message: 'Unauthorized' });
}
const split = authorization.split('Bearer ')
if (split.length !== 2) {
console.log('[Invalid Authorization Param')
return res.status(401).send({ message: 'Unauthorized' });
}
const token = split[1] //this is your token to use with jwt.verify
When you sending the token in postman, select Bearer Token
When you start creating your frontend, the codes should be equivalent to the following fetch request
fetch('/api/path', { method: 'GET', headers: { "Authorization": `Bearer ${token}`}}).(res => res.json())
May change method to your desire method (e.g get or post), and the token will be the the jwt token

req.user is undefined when using Passport-jwt on fetch user

I already checked multiple answers on Stackoverflow, and also went through on the documentation but I still cannot figure out my problem. when I try to sign in and signup it's working perfectly I have my token. It's nightmare to just fetch my current_user get('/isAuth') I get undefined !!!!
const Authentication = require("../controllers/authentication");
const passport = require("passport");
const requireAuth = passport.authenticate('jwt', {session: false});
const requireSignin = passport.authenticate('local', {session: false});
module.exports = app => {
app.post('/signup', Authentication.signup);
app.post('/signin', requireSignin, Authentication.signin);
// Current User is undefined !!!!!
app.get('/isAuth', Authentication.fetchUser);
my passport.js
const keys = require("../config/keys");
const passport = require("passport");
const User = require("../models/User");
const JwtStrategy = require("passport-jwt").Strategy;
const ExtractJwt = require('passport-jwt').ExtractJwt;
const localStrategy = require("passport-local");
// Create local strategy
const localOptions = { usernameField: "email" };
const localLogin = new localStrategy(localOptions, function(email,password,done) {
// verify this username and password, call done with the user
// if it is the correct username and password
// otherwise, call done with false
User.findOne({ email: email }, function(err, user) {
if (err) {return done(err);}
if (!user) {return done(null, false);}
// compare passwords - is password is equal to user.password?
user.comparePassword(password, function(err, isMatch) {
if (err) {return done(err);}
if (!isMatch) {return done(null, false);}
return done(null, user);
});
});
});
// setup option for jwt Strategy
const jwtOptions = {
jwtFromRequest: ExtractJwt.fromHeader('authorization'),
secretOrKey: keys.secret
};
// Create Jwt strategy
const jwtLogin = new JwtStrategy(jwtOptions, function(payload, done) {
// See if the user Id in the payload exists in our database
// If does, call 'done' with that other
// otherwise, call done without a user object
User.findById(payload.sub, function(err, user) {
if (err) {return done(err, false);}
if (user) {
done(null, user);
} else {
done(null, false);
}
});
});
// Tell passport to use this strategy
passport.use(jwtLogin);
passport.use(localLogin);
// Generate token
passport.serializeUser((user, done) => {
done(null, user.id);
});
passport.deserializeUser((id, done) => {
User.findById(id).then(user => {
done(null, user);
});
});
./controller/authentication.js
const User = require('../models/User');
const jwt = require('jwt-simple');
const config = require('../config/keys');
function tokenForUser(user){
const timestamp = new Date().getTime();
return jwt.encode({sub: user.id, iat: timestamp}, config.secret);
}
exports.signup = function(req,res,next){
console.log(req.body)
const email = req.body.email;
const password = req.body.password;
if(!email || !password){
return res.status(422).send({error: 'You must provide email and password'});
}
// See if user with the given email exists
User.findOne({email: email}, function(error, existingUser){
if (error){return next(error)};
// if a user with email does exist, return an error
if (existingUser){
return res.status(422).send({error: 'Email is in use'});
}
// if a user with email does not exist, create and save record
const user = new User({
email: email,
password: password
});
user.save(function(error){
if (error){return next(error);}
// respond to request indicating the user was created
res.json({token: tokenForUser(user)});
})
})
}
exports.signin = function (req,res,next){
// user has already had their email and password auth
// we just need to give them a token
res.send({token: tokenForUser(req.user)});
}
// here is my problem...
exports.fetchUser = function (req, res, next) {
console.log('this is ',req.user)
};
Still stuck for many days... it's a nightmare!!! if someone has the solution.
after sign in if I want to go to my route /isAuth to check my user data:
Have your tried using a middleware that calls the isAuthenticated function on req object? This function is added by passport and is generally the recommended way to check if a request is authenticated.
function isLoggedIn(req, res, next) {
if (req.isAuthenticated()) {
return next();
}
res.redirect("/");
}
Then you can call this function when a user hits your isAuth route:
app.get('/isAuth', isLoggedIn, Authentication.fetchUser);

Categories

Resources