AMcoder - javascript, python, java, html, php, sql

Express.js. Սխալների մշակումից հետո կատարումը չի դադարում: Ինչո՞ւ։

Ես գրել եմ էքսպրես հավելված՝ REST API ստեղծելու համար:

Քանի որ ես դա հասկանում եմ, եթե ես ուղարկում եմ անվավեր նշանով վերնագիր, jwt.verify-ը սահմանում է err (JsonWebTokenError), որը փոխանցվում է իմ սխալների մշակողին և այն ուղարկում է 401:

res.status(401).send({
        success: false,
        message: err.name
});

Եվ մահապատիժը պետք է ավարտվի: Բայց փոխարենը ես ստանում եմ սա.

Start token verification
Error before: JsonWebTokenError
JsonWebTokenError: invalid signature
at Object.module.exports.verify (/srv/lonja/node_modules/jsonwebtoken/index.js:129:17)
at /srv/lonja/app/routes/api.js:76:17
at Layer.handle [as handle_request] (/srv/lonja/node_modules/express/lib/router/layer.js:82:5)
at trim_prefix (/srv/lonja/node_modules/express/lib/router/index.js:302:13)
at /srv/lonja/node_modules/express/lib/router/index.js:270:7
at Function.proto.process_params (/srv/lonja/node_modules/express/lib/router/index.js:321:12)
at next (/srv/lonja/node_modules/express/lib/router/index.js:261:10)
at Function.proto.handle (/srv/lonja/node_modules/express/lib/router/index.js:166:3)
at router (/srv/lonja/node_modules/express/lib/router/index.js:35:12)
at Layer.handle [as handle_request] (/srv/lonja/node_modules/express/lib/router/layer.js:82:5)
This is the last message related to[object Object]
GET /api/home_gallery/ 401 20.834 ms - 47
_http_outgoing.js:335
throw new Error('Can\'t set headers after they are sent.');
      ^
Error: Can't set headers after they are sent.
at ServerResponse.OutgoingMessage.setHeader (_http_outgoing.js:335:11)
at ServerResponse.header (/srv/lonja/node_modules/express/lib/response.js:700:10)
at ServerResponse.send (/srv/lonja/node_modules/express/lib/response.js:154:12)
at ServerResponse.json (/srv/lonja/node_modules/express/lib/response.js:240:15)
at /srv/lonja/app/routes/api.js:214:17
at /srv/lonja/node_modules/mongoose/node_modules/kareem/index.js:103:16
at process._tickCallback (node.js:355:11)

Այսպիսով, սխալների մշակումից հետո երթուղու մշակիչը գործարկվում է, և ես չեմ հասկանում, թե ինչու:

Իմ կոդը (միայն համապատասխան բիթերը).

var User = require('../models/user');
var myImage = require('../models/image');
var jwt = require('jsonwebtoken');
var config = require('../../config');

// super secret for creating tokens
var superSecret = config.secret;

module.exports = function(app, express) {

    var apiRouter = express.Router();

Ես օգտագործում եմ միջին ծրագրի այս հատվածը՝ jsonwebtoken-ը ստուգելու համար.

   // route middleware to verify a token
apiRouter.use(function(req, res, next) {
    // do logging
    console.log('Start token verification');

    // check header or url parameters or post parameters for token
    var token = req.body.token || req.params.token || req.headers['x-access-token'];

    // decode token
    // verifies secret and checks exp
    if (token) {
        jwt.verify(token, superSecret, function(err, decoded) {
            if (err) {
                return next(err);
            }
            // if everything is good, save to request for use in other routes
            else req.decoded = decoded;
        });
    }
    // if there is no token
    // return an HTTP response of 401 (access unauthorized) and an error message
    else {
        var noToken = new Error('Error_NoTokenProvided');
        return next(noToken);
    }
    next(); // make sure we go to the next routes and don't stop here
});

Ավելի ուշ կոդի մեջ ես ստացել եմ այս երթուղու մշակիչը.

apiRouter.route('/home_gallery')
// get all the images
.get(function(req, res) {
    myImage.find(function(err, images) {
        if (err) res.send(err);
        // return the users
        res.json(images);
    });
});

Եվ վերջապես, այս վերջին միջանկյալ ծրագրակազմը սխալների կառավարումն անելու համար.

apiRouter.use(function(err, req, res, next) {
    console.log('Error before: ' + err.name);
    if (err.name == 'Error_NoTokenProvided' ||
        err.name == 'JsonWebTokenError') {
        res.status(401).send({
            success: false,
            message: err.name
        });
    } else if (err.name == 'TokenExpiredError') {
        res.redirect('/login');
    } else {
        res.status(500).send({
            success: false,
            message: err.name
        });
    }
    console.log(err.stack);
    console.log('This is the last message related to' + req);
});

Պատասխանները:


1

Խնդիրը կարծես սա է.

if (token) {
    jwt.verify(token, superSecret, function(err, decoded) {
        if (err) {
            return next(err);
        }
        // if everything is good, save to request for use in other routes
        else req.decoded = decoded;
    });
} else { ... }
next();

Քանի որ jwt.verify()-ը ասինքրոն մեթոդ է, այդ ֆունկցիայի կանչից հետո մշակումը շարունակվում է, ինչը նշանակում է, որ կանչվում է ներքևի next()ը: Եթե ​​նշանի ստուգումը ձախողվի, դուք զանգահարեք next(err); այլ կերպ ասած, դու երկու անգամ զանգում ես next()ին:

Հնարավոր լուծումներից մեկը կլինի.

if (token) {
    // We use `return` only to stop further processing of the middleware,
    // we don't actually care about the return value from `jwt.verify()`.
    return jwt.verify(token, superSecret, function(err, decoded) {
        if (err) {
            return next(err);
        }
        // if everything is good, save to request for use in other routes
        else {
          req.decoded = decoded;
          next();
        }
    });
}

Նման մի բան տեղի է ունենում ձեր երթուղու կարգավորիչում.

if (err) res.send(err);
// return the users
res.json(images);

Եթե ​​err-ը դրված է, դուք զանգահարում եք և՛ res.send(), և՛ res.json(), քանի որ res.send() զանգահարելը հրաշքով չի դադարեցնում մնացած կոդի հետագա մշակումը:

Նմանատիպ լուծում, ինչպես վերը նշվածը, կարող է օգտագործվել.

if (err) return res.send(err);
res.json(images);

Կամ, եթե նախընտրում եք.

if (err) {
  res.send(err);
} else {
  res.json(images);
}
04.05.2015
  • Ես մտածում էի այս մասին և կասկածում եմ՝ արդյոք մենք չենք փոխակերպում կոդը համաժամանակյա՝ կատարելով այս բոլոր if else հայտարարությունները: Կատարումը պետք է սպասի asyncroous զանգին, որպեսզի կարողանա շարունակել կատարումը, թե՞ ինչ-որ բան բաց եմ թողնում: 18.05.2015
  • @mvillar async ֆունկցիան այստեղ jwt.verify() է, և մենք սպասում ենք, որ այն ավարտվի մինչև next()-ը կանչվի (այն կանչվում է ավարտի հետ կանչում jwt.verify()-ին): if/else-ը միայն տարբերելու համար է, թե որ զանգը պետք է կատարի next()ին: 18.05.2015
  • Նոր նյութեր

    Օգտագործելով Fetch Vs Axios.Js-ը՝ HTTP հարցումներ կատարելու համար
    JavaScript-ը կարող է ցանցային հարցումներ ուղարկել սերվեր և բեռնել նոր տեղեկատվություն, երբ դա անհրաժեշտ լինի: Օրինակ, մենք կարող ենք օգտագործել ցանցային հարցումը պատվեր ներկայացնելու,..

    Տիրապետել հանգստության արվեստին. մշակողի ուղեցույց՝ ճնշման տակ ծաղկելու համար
    Տիրապետել հանգստության արվեստին. մշակողի ուղեցույց՝ ճնշման տակ ծաղկելու համար Ինչպե՞ս հանգստացնել ձեր միտքը և աշխատեցնել ձեր պրոցեսորը: Ինչպես մնալ հանգիստ և զարգանալ ճնշման տակ...

    Մեքենայի ուսուցում բանկային և ֆինանսների ոլորտում
    Բարդ, խելացի անվտանգության համակարգերը և հաճախորդների սպասարկման պարզեցված ծառայությունները բիզնեսի հաջողության բանալին են: Ֆինանսական հաստատությունները, մասնավորապես, պետք է առաջ մնան կորի..

    Ես AI-ին հարցրի կյանքի իմաստը, այն ինչ ասում էր, ցնցող էր:
    Այն պահից ի վեր, երբ ես իմացա Արհեստական ​​ինտելեկտի մասին, ես հիացած էի այն բանով, թե ինչպես է այն կարողանում հասկանալ մարդկային նորմալ տեքստը, և այն կարող է առաջացնել իր սեփական արձագանքը դրա..

    Ինչպես սովորել կոդավորումը Python-ում վագրի պես:
    Սովորելու համար ծրագրավորման նոր լեզու ընտրելը բարդ է: Անկախ նրանից, թե դուք սկսնակ եք, թե առաջադեմ, դա օգնում է իմանալ, թե ինչ թեմաներ պետք է սովորել: Ծրագրավորման լեզվի հիմունքները, դրա..

    C++-ի օրական բիթ(ե) | Ամենաերկար պալինդրոմային ենթաշարը
    C++ #198-ի ամենօրյա բիթ(ե), Ընդհանուր հարցազրույցի խնդիր. Ամենաերկար պալինդրոմային ենթատող: Այսօր մենք կանդրադառնանք հարցազրույցի ընդհանուր խնդրին. Ամենաերկար palindromic substring...

    Kydavra ICAReducer՝ ձեր տվյալների ծավալայինությունը նվազեցնելու համար
    Ի՞նչ է ICAReducer-ը: ICAReducer-ն աշխատում է հետևյալ կերպ. այն նվազեցնում է նրանց միջև բարձր փոխկապակցված հատկանիշները մինչև մեկ սյունակ: Բավականին նման է PCAreducer-ին, չնայած այն..