在获取用户时使用 Passport-jwt 时 req.user 未定义

Posted

技术标签:

【中文标题】在获取用户时使用 Passport-jwt 时 req.user 未定义【英文标题】:req.user is undefined when using Passport-jwt on fetch user 【发布时间】:2019-12-10 04:04:46 【问题描述】:

我已经在 *** 上检查了多个答案,并且还查看了文档,但我仍然无法弄清楚我的问题。当我尝试登录并注册时,它运行良好,我有我的令牌。只获取我的 current_user get('/isAuth') 是一场噩梦,我得到了 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);

我的护照.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)
  ;

仍然卡了很多天......这是一场噩梦!如果有人有解决方案。

登录后如果我想去我的路线 /isAuth 检查我的用户数据:

【问题讨论】:

你能在堆栈跟踪中添加完整的控制台输出吗? @Peter 登录后我想检查我的当前用户,但仍未定义...检查我的控制台日志 你知道如何使用调试器吗?可能想在 isAuth 路由中设置断点。 【参考方案1】:

您是否尝试过使用在 req 对象上调用 isAuthenticated 函数的中间件?这个功能是passport添加的,一般推荐用来检查请求是否被认证。

function isLoggedIn(req, res, next) 
  if (req.isAuthenticated()) 
    return next();
  

  res.redirect("/");

然后你可以在用户点击你的isAuth路由时调用这个函数:

app.get('/isAuth', isLoggedIn, Authentication.fetchUser);

【讨论】:

什么是未定义的?您添加的屏幕截图没有帮助

以上是关于在获取用户时使用 Passport-jwt 时 req.user 未定义的主要内容,如果未能解决你的问题,请参考以下文章

NodeJs Express passport-jwt 从令牌中获取错误的用户

如何使用passport-jwt在nodejs中发送/提取JWT令牌?

Passport-jwt 不同的令牌相同的结果

NodeJs:错误401(未经授权)我正在使用passport-jwt

我可以有条件地使用passport-jwt吗?

设置 passport-jwt 身份验证