簡體   English   中英

節點快遞護照(JWT) - 認證后的回叫

[英]Node express passport (JWT) - callback after auth

我有使用護照JWT的身份驗證,但是只有在用戶通過身份驗證后才能運行回調函數/響應。 如何才能做到這一點?

在我的路線:

import express from 'express';
import passport from '../../config/passport';
import memberInfoCtrl from '../controllers/memberInfo';

const router = express.Router();

router.route('/members')
  .get(membersCtrl.tokenCheck, passport.authenticate('jwt', { session: false }), membersCtrl.doSomethingElse);

export default router;

如果身份驗證成功,我希望運行membersCtrl.doSomethingElse

這是我的tokenCheck功能:

function tokenCheck(req, res, next) {
  const token = getToken(req.headers);
  if (token) {
    const decoded = jwt.decode(token, config.secret);
    User.findOne({
      email: decoded.email
    }, (err, user) => {
      if (err) throw err;

      if (!user) {
        return res.status(403).send({
          success: false, msg: 'Authentication failed. User not found.'
        });
      }
      // res.json({ success: true, msg: 'Welcome to the member area!' });
      return next();
    });
  } else {
    return res.status(403).send({ success: false, msg: 'No token provided.' });
  }
}

tokenCheck使用res.json工作正常,但之后不會調用doSomethingElse函數。

我以為是因為我們發送了這樣的回復:

res.json({ success: true, msg: 'Welcome to the member area!' });

return next();替換res.json return next(); 返回錯誤:

Error: Unknown authentication strategy \\"jwt\\"

為什么會發生這種情況 - 如何在執行另一個功能之前檢查相同路由的身份驗證?

我確定這是一件我很想念的傻事。 任何幫助表示贊賞!

這是我的主要快遞腳本的一部分,初始化護照:

import passport from 'passport';
...
app.use(passport.initialize());

app.use('/api', routes);
...

護照配置:

const JwtStrategy = require('passport-jwt').Strategy;
import User from '../server/models/user';
import config from './env';

module.exports = (passport) => {
  const opts = {};
  opts.secretOrKey = config.secret;
  passport.use(new JwtStrategy(opts, (jwtPayload, done) => {
    User.findOne({ id: jwtPayload.id }, (err, user) => {
      if (err) {
        return done(err, false);
      }
      if (user) {
        done(null, user);
      } else {
        done(null, false);
      }
    });
  }));
};

你的一般方法是正確的。 要根據某些條件保護路由,請編寫調用next()的自定義中間件next()如果滿足這些條件next()

但在你的情況下,這不是必要的,因為這是passport-jwt作用。 所以假設您正確配置了passportpassport-jwt ,您需要編寫的是:

router.route('/members')
    .get(passport.authenticate('jwt', { session: false }), membersCtrl.doSomethingElse);

passport-jwt將從請求中提取JWT並根據您提供的秘密或密鑰進行驗證。 之后,它將使用passport的verify回調來填充req.user )。

另外:使用res.json()后發送一個響應,這就是為什么你的護照中間件和其他任何東西都沒有達到的原因。

關於您的錯誤Error: Unknown authentication strategy \\"jwt\\" :如果您沒有正確配置您的護照身份驗證,通常會發生這種情況。 如果你把它包含在你的問題中,我會看一下並相應地擴展我的答案。

更新:您的代碼看起來不錯,除了一件事:您沒有在passport-jwt選項中指定jwtFromRequest屬性,這是強制性的。 或者你有沒有機會忘記調用你的護照配置?

更新2:關於我的評論的進一步說明如下:
1.)在主快捷腳本中導入您的ES6護照配置模塊( 您在其中添加了jwtFromRequest選項 )並調用它:

import passport from 'passport';
import passportConfig from 'path/to/passport/config';
...
app.use(passport.initialize());
passportConfig(passport);
...

2.)確保刪除tokenCheck功能,您不需要它。 請參閱本答案的第一部分。

更新3: '未授權'很棒,因為這意味着您現在成功保護您的/members路線。 要實現基於令牌的身份驗證,您現在需要一個額外的路由/authenticate ,用戶可以請求訪問您的Web服務,例如通過提供憑據(您的路由將驗證這些憑據並使用JWT進行響應,必須使用相同的秘密進行簽名)用於passport-jwt - 否則passport-jwt將無法在以后驗證令牌簽名。

但這超出了這個問題的范圍。 應該有很多資源可以解決這個問題。 例如,您可以實施/authenticate中使用路由jsonwebtoken這是在顯示這篇文章 (他們沒有用passport都而是用jsonwebtoken令牌創建驗證)。

注意:如果您還要實現客戶端,則必須在其中包含一些額外的邏輯來存儲JWT並將其包含在您對Express應用程序的請求中。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM