首页 > 解决方案 > Passport js 中的 isAuthenticated() 总是返回 false

问题描述

我一直在浏览论坛,但我无法在我的代码中找到错误,它总是导致错误,我无法解决它,请帮助我......有没有其他方法来验证用户而不是护照所以我可以使用它。我正在添加更多句子,因为它不允许我发布我的查询,对不起..

const http = require("http"),
  hostname = "127.0.0.1",
  port = 3000,
  bodyParser = require("body-parser"),
  mongoose = require("mongoose"),
  express = require("express"),
  passport = require("passport"),
  localStrategy = require("passport-local"),
  passportLocalMongoose = require("passport-local-mongoose"),
  User = require("./models/user");
app = express();
mongoose.connect("mongodb://localhost/drive", { useNewUrlParser: true });
app.set("view engine", "ejs");
app.use(express.static("public"));
app.use(passport.initialize());
app.use(passport.session());
app.use(
  require("express-session")({
    secret: "Beta tumse na ho payega",
    resave: false,
    saveUninitialized: false
  })
);
passport.use(new localStrategy(User.authenticate()));
passport.serializeUser(User.serializeUser());
passport.deserializeUser(User.deserializeUser());
app.use(bodyParser.urlencoded({ extended: true }));
const server = http.createServer((req, res) => {
  res.statusCode = 200;
  res.setHeader("Content-Type", "text/plain");
});
app.get("/", function(req, res) {
  res.render("index");
});
app.get("/register", function(req, res) {
  res.send("hello");
});
app.get("/login", function(req, res) {
  res.render("login");
});
app.post(
  "/login",
  passport.authenticate("local", {
    successRedirect: "/",
    failureRedirect: "/login"
  }),
  function(req, res) {}
);

app.get("/logout", function(req, res) {
  req.logout();
  res.redirect("/");
});

function isLoggedIn(req, res, next) {
  if (req.isAuthenticated()) {
    return next();
  } else {
    console.log("Not logged");
    res.redirect("/login");
  }
}
app.get("/secret", isLoggedIn, function(req, res) {
  res.send("You are logged in");
});
app.post("/register", function(req, res) {
  if (req.body.password === req.body.cpassword) {
    User.register(
      new User({ username: req.body.username }),
      req.body.password,
      function(err, user) {
        if (err) console.log(err);
        else
          passport.authenticate("local")(req, res, function() {
            res.send("signed up");
          });
      }
    );
  } else res.send("Password Mismatch");
});
//DRIVE SCHEMA
//var driveSchema = mongoose.Schema({
//  title: String,
//  created: { type: Date, default: Date.now }
//});
app.listen(port, hostname, function() {
  console.log("Server is running at " + hostname + "/" + port);
});

//./models/user.js  file

const mongoose = require("mongoose"),
  passportLocalMongoose = require("passport-local-mongoose");
var UserSchema = new mongoose.Schema({
  username: String,
  password: String
});
UserSchema.plugin(passportLocalMongoose);
module.exports = mongoose.model("User", UserSchema);

标签: javascriptnode.jspassport.js

解决方案


我已经使用passportjwt库来验证和维护用户的会话。无需在服务器端维护用户会话。

apis/apis.js :此文件包含所有 apis 端点。/loginurl 将使用护照对用户进行身份验证,并使用 jwt 向客户端发送令牌

const passport = require('passport')
const expRoute = require('express').Router();
let exporter = process.exporter;
expRoute.post('/login', (req, res, next) => {
  passport.authenticate(
    'local', 
    { 
        // successRedirect: '/',
        // failureRedirect: '/login',
        successFlash: 'Welcome!',
        failureFlash: 'Invalid username or password.' 
    },
    (err, user, info) => {
        if (err) {
            return res.status(500).json(err)
        }
        else if (user) {
            return res.status(200).json({
                token: exporter.generateToken(user)
            })
        }
        else {
            return res.status(400).json(info)
        }
    }
  )(req, res, next);
})
expRoute.get('/view', exporter.authenticateToken, (req, res) => {
    let param = req.finalTokenExtractedData
    if (param && exporter.isObjectValid(param, 'tokenId', true, true)) {
        let condition = {
            _id: param.tokenId
        }
        let options = {
            _id: 0,
            password: 0,
            __v: 0
        }
        process.USER.findOne(condition, options) // mongo find
        .then((data) => {
            res.status(200).json({
                 result: data,
                 msg: 'success'
            })
        })
       .catch((mongoErr) => {
            exporter.logNow(`USER mongo Error: ${mongoErr}`)
            res.status(400).json({
                msg: 'user not found'
            })
        })
    }
    else {
        res.status(404).json({
            msg: 'invalid token'
        })
    }
})
module.exports = expRoute

common/env.js:该文件将初始化所有连接,例如 mongo,需要几个文件将用作全局

process.CONFIG = require('../configs/config.json')

process.exporter = require("../lib/exporter.js")

process.dbInit = (globalName, mongoUrl, collectionName) => {
    require("../models/db-init.js")(mongoUrl, collectionName)
    .then((modelObj) => {
        process[globalName] = modelObj // will be used as global
    })
    .catch((dbInitErr) => {
        process.exporter.logNow(`dbInit Error: ${dbInitErr}`)
        process.exit()
    });
}

lib/exporter.js:这个文件有导出器类,它包含所有主要功能,如 mongo 连接、authenticateToken、verifyPassword 等。

const fs = require('fs'),
    redis = require("redis"),
    path = require("path"),
    mongoose = require('mongoose'); mongoose.set('useCreateIndex', true);
const Schema = mongoose.Schema;
var bcrypt = require('bcryptjs')
var jwt = require('jsonwebtoken')

class Exporter  {
    mongoConnection(mongoURI, schemaObj) {
        return new Promise(async (resolve, reject) => {
            if (!mongoURI || typeof mongoURI == 'undefined' || mongoURI.length < 1)
                return reject('invalid mongo connection url');
            return resolve(mongoose.createConnection(mongoURI, { useNewUrlParser: true }))
        })
    }
    createMongoSchema(schemaObj) {
        return (new Schema(schemaObj));
    }
    createMongoModel(mongoDB, collectionName, newSchema) {
        if (newSchema)
            return mongoDB.model(collectionName, newSchema)        
        return mongoDB.model(collectionName)
    }
    authenticateToken(req, res, next) {
        const bearerHeader = req.header('authorization')
        if (typeof bearerHeader != 'undefined') {
            const bearer = bearerHeader.split(' ')
            const bearerToken = bearer[1] 
            jwt.verify(bearerToken, process.CONFIG.jwt.token.activated, (err, data) => {
                if (err)
                    res.status(400).json({
                        msg: "Invalid token or please try to login again"
                    })
                else {
                    process.exporter.getSingleHashKeysValuesFromRedis('expired_token', bearerToken)
                    .then((redisTokendata) => {
                        if (redisTokendata)
                            res.status(400).json({
                                msg: "token expired"
                            })
                        else {
                            req.finalTokenExtractedData = data
                            // if (req.originalUrl.trim() == process.logoutURL.trim())
                                req.jwtToken = {
                                    token: bearerToken,
                                    secret: process.CONFIG.jwt.token.activated
                                }
                            next()
                        }
                    })
                    .catch((redisTokenError) => {
                        process.exporter.logNow(`redis token error: ${redisTokenError}`)
                        res.status(400).json({
                            msg: "Some went wrong while checking token. Please try later."
                        })
                    })
                }
            })
        }
        else 
            res.status(400).json({
                msg: "invalid token"
            })
    }
    generateToken(data) {
        let expiry = new Date();
        // expiry.setDate(expiry.getDate() + 7)
        expiry.setMinutes(expiry.getMinutes() + 5)
        return jwt.sign({
            tokenId: data._id,
            exp: parseInt(expiry.getTime() / 1000),
        }, process.CONFIG.jwt.token.activated)
    }    
    createPassword(password) {
        return new Promise((resolve, reject) => {
            if (typeof password == 'undefined' && password == '')
                return reject('password empty')
            bcrypt.hash(password, 10, async (bErr, hash) => {
                if (bErr)
                    reject(bErr)
                else
                    resolve(hash)
            })
        })
    }
    verifyPassword(enteredPassword, savePassword) {
        return bcrypt.compareSync(enteredPassword, savePassword)
    }
}
module.exports = (new Exporter());

index.js:这是您将执行的文件node index.js

const express = require('express');
const path = require('path');
const bodyParser = require('body-parser');
const passport = require('passport');

require('./common/env')
require('./configs/passport')

const app = express()

const cors = require('cors')
app.use(cors());
app.use(bodyParser.json())
app.use(bodyParser.urlencoded({ extended: true}))
app.use(passport.initialize())

app.use(function(req, res, next) {
    res.header("Access-Control-Allow-Origin", "*");
    res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
    next();
});

let apis = require('./apis/api')
app.use('/user', apis)

/**
 * 404 Handler
 */
app.use((req, res, next)=>{
    return res.status(404).send("Endpoint "+req.url +" not found");
})

/**
 * if any error or exception occurred then write into a JS file so that app can be restarted
 */
process.on('uncaughtException', (err) => {
    console.error(err.stack);
});


app.listen(3000, function(server) {
    console.log("App listening at 3000");
});

当 index.js 文件成功执行并监听 3000 端口,然后使用此 URLhttp://localhost:3000/user/login进行身份验证,它将接受您的用户名和密码,然后使用护照进行身份验证并将令牌作为响应发送给客户端。令牌可以包含加密形式的用户数据并具有到期时间。

参考链接:https ://github.com/arjun-707/login-logout-jwt-nodejs


推荐阅读