passport.authenticate () вызывается дважды только при ошибке - PullRequest
0 голосов
/ 07 февраля 2019

Я аутентифицирую пользователя, используя аутентификацию Ldap.Это прекрасно работает во время успешной аутентификации или когда пользователь вводит неверные учетные данные.Но в случае возникновения ошибки функция passport.authenticate () вызывается дважды, и я получаю следующую ошибку.

_http_outgoing.js:470
throw new ERR_HTTP_HEADERS_SENT('set');
^

Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the 
client

Так почему функция passport.authenticate вызывается дважды только при ошибке.Ниже приведен код, используемый для аутентификации.

let callCnt = 0

function pPortAuth(req,res,next) {
//Fetch the roles of the gid from the database
console.log("Called Here")
passport.authenticate('ldapauth', { session: false }, function (err, user, 
info) {
    console.log("Hetre " + req.method)
    ++callCnt
    console.log(callCnt)

    if (err || !user) {
        if (err && (err.code == 'ETIMEDOUT' || err.code == 'ENOTFOUND')) {
            console.log("Could not reach Ldap Server" + err.code)

            return res.status(400).json({ success: false, message: 'Could 
    not reach Ldap Server' })
        }else if(!user){
            console.log("Authentication Failed or not a valid user")
        return res.status(400).json({ success: false, message: 
   'Authentication Failed' });
        }
    }

    let roles = (user.sAMAccountName == 'g705615')?['readWrite']: 
    ['readOnly']
    console.log(roles)
    return res.send({
        success: true,
        gid: user.sAMAccountName,
        name: user.name,
        token: jwt.sign({ sub: user.sAMAccountName, roles: roles, 
   loggedInUsername: user.name }, config.secret)
    });
})(req,res,next)
}

А ниже - журнал

Called Here
Hetre POST
1
Could not reach Ldap ServerENOTFOUND
Hetre POST
2
Could not reach Ldap ServerENOTFOUND

Если вы видите, что функция function pPortAuth(req,res,next) вызывается только один раз, а функция passport.authenticate()Вызван дважды при ошибке.

Может кто-нибудь сказать, пожалуйста, где я делаю ошибку

ОБНОВЛЕНИЕ

//users.controller.js
let express = require('express');
let userAuth = express.Router();
let expressJwt = require('express-jwt');
let passport = require('passport') 
let config = require("../config.json")
let userAuthSvc = require('../_services/user.service')

let Ldap = require('../config/ldap.config');

passport.serializeUser((user, done) => {
done(null,user)
})
passport.deserializeUser((user,done) => {
done(null,user)
})

passport.use(Ldap)

let initializePport = passport.initialize();

//userAuth.use(userAuthSvc.pportInit);
userAuth.post('/ldapLogin',initializePport, authenticate)

function authenticate (req, res, next) {
userAuthSvc.pportAuth(req, res, next);
}

//user.service.js
let passport = require('passport') 

function pPortAuth(req,res,next) {
//Fetch the roles of the gid from the database
console.log("Called Here")
passport.authenticate('ldapauth', { session: false }, function (err, user, 
info) {
    console.log("Hetre " + req.method)
    ++callCnt
    console.log(callCnt)

    if (err || !user) {
        if (err && (err.code == 'ETIMEDOUT' || err.code == 'ENOTFOUND')) {
            console.log("Could not reach Ldap Server" + err.code)

            return res.status(400).json({ success: false, message: 'Could 
  not reach Ldap Server' })
        }else if(!user){
            console.log("Authentication Failed or not a valid user")
        return res.status(400).json({ success: false, message: 
 'Authentication Failed' });
        }
    }

    let roles = (user.sAMAccountName == 'g705615')?['readWrite']: 
 ['readOnly']
    console.log(roles)
    return res.send({
        success: true,
        gid: user.sAMAccountName,
        name: user.name,
        token: jwt.sign({ sub: user.sAMAccountName, roles: roles, 
 loggedInUsername: user.name }, config.secret)
    });
 })(req,res,next)
 }

1 Ответ

0 голосов
/ 12 апреля 2019

Единственный обходной путь, который я мог найти для моей проблемы, состоял в том, чтобы предотвратить отправку ответа дважды.Я думаю, что проблема в том, что когда функция passport.authenticate() обнаруживает ошибку ENOTFOUND, она снова вызывает функцию обратного вызова, так как я считаю, что она не обрабатывается должным образом.Поэтому, чтобы преодолеть эту проблему, я просто поставил проверку, чтобы увидеть, были ли заголовки уже отправлены, и если да, то просто вернитесь из функции, иначе отправьте ответ.Ниже приведен мой код, пожалуйста, прокомментируйте его, если вам нужна помощь.

app.post('/ldapLogin', function (req, res, next) {
passport.authenticate('ldapauth', { session: false }, function (err, user, info) {

    let resObj = {}
    let resStatus 
    if (err || !user) {
        if (err && (err.code == 'ETIMEDOUT' || err.code == 'ENOTFOUND')) {
            resStatus = res.status(400)
            resObj['success'] = false
            resObj['message'] = 'Could not reach Ldap Server'

        }else if(!user){
            console.log("Authentication Failed or not a valid user")
            resStatus = res.status(400)
            resObj['success'] = false
            resObj['message'] = 'Authentication Failed'
        }
    }else{
        resStatus = res
        let roles = (user.sAMAccountName == 'xxxxx')?['readWrite']:['readOnly']
        resObj['success'] = true
        resObj['gid'] = user.sAMAccountName
        resObj['name'] = user.name
        resObj['token'] = jwt.sign({ sub: user.sAMAccountName, roles: roles, loggedInUsername: user.name }, config.secret)
    } 
    if(res.headersSent)
    return
    return resStatus.send(resObj);
})(req, res, next)
})
...