Узел - паспорт-http, как вернуть ответ JSON, если не удалось - PullRequest
0 голосов
/ 26 июня 2018

Я создаю API, используя Node / Express / Typescript / Passport

У меня есть конечная точка, которая должна быть защищена «Базовой аутентификацией», которая берет имя пользователя и пароль, преобразует его в base64 и добавляет его в заголовок авторизации.

В частности, я использовал следующую зависимость PassportJS. http://www.passportjs.org/docs/basic-digest/

Однако ответ при сбое аутентификации меньше желаемого. Я создал API, и поэтому, если эта аутентификация не удалась, я бы хотел, чтобы он возвращал ответ json, а не то, что показано ниже.

Ответ:

<code><!DOCTYPE html> <html lang="en">
    <head>
        <meta charset="utf-8">
        <title>Error</title>
    </head>
    <body>
        <pre>error

паспорт

import { Passport } from 'passport';
import { BasicStrategy } from 'passport-http';
import Config from './../config/config';

class PassportMiddleware {

    public passport: any;
    public config: any;

    constructor() {

        this.passport = new Passport();
        this.config = new Config();


        this.basicStrategy();

    }

    private basicStrategy(): void {

        this.passport.use(new BasicStrategy( (username, password, done) => {

            const credentials = this.config.hs;

            if (credentials.username !== username && credentials.password !== password) {


                 // Needs to be json response error res.status(400).json('error');
                return done("error", false)
            }

            return done(null, null);
        }));

    }
}

export default new PassportMiddleware().passport;

маршрутизатор

import { Router } from 'express';

import TransactionController from './transaction.controller'; 
import PassportMiddleware from './../../middleware/passport.middleware';


class TransactionRouter {

    router: Router;
    controller: any;
    guard: any;

    constructor() {

        this.router = Router();
        this.controller = new TransactionController();
        this.guard = PassportMiddleware.authenticate('basic', { session: false });

        this.router.post('/', this.controller.store.bind(this.controller));
        this.router.get('/:id', this.controller.show.bind(this.controller));
        this.router.post('/callback', this.guard, this.controller.callback.bind(this.controller));

    }
}

export default new TransactionRouter().router;

контроллер

import { Request, Response, NextFunction } from 'express';

import Config from './../../config/config';

class TransactionController {

    public config: any;

    constructor() {

        this.config = new Config();

    }

    public async callback(req: Request, res: Response): Promise<any> {


    }
}

export default TransactionController;

1 Ответ

0 голосов
/ 26 июня 2018

См. Раздел «Пользовательский обратный вызов» в http://www.passportjs.org/docs/

Вы можете сделать что-то вроде: (извините за отсутствие типов)

// passport -> basicStrategy
// Failed authentication should not be considered as an error,
// therefore, use `null` and false to indicate a failed authentication
// and a third parameter to indicate to reason 
return done(null, false, {error : 'Incorrect username or passport'});

// router
this.guard = (req, res, next) => {
  PassportMiddleware.authenticate('basic', (err, user, info) => {
    if (err) return next(err);
    // info -> {error : 'Incorrect username or passport'}
    if (!user) return res.status(401).json(info);
    req.user = user;
    next();
  })(req, res, next);
};
...