#typescript #express #passport.js
#typescript #выразить #passport.js
Вопрос:
Я новичок в разработке JavaScript / TypeScript, и в настоящее время я расширяю приложение Express с помощью единого входа в систему. Приложение Express использует среду routing-controllers для обработки запросов и должно использовать passport-saml для аутентификации. Мне уже удалось заставить аутентификацию работать со стандартными маршрутами express:
export class SsoRoutes {
public router: Router;
constructor() {
this.router = Router();
}
this.router.get('/login-sso', passport.authenticate('saml'));
this.router.post('/login-sso/consume', passport.authenticate('saml', {
failureRedirect: '/',
failureFlash: true,
session: false
}), function (req, res) {
// handle callback
});
}
Но я не могу понять, как использовать passport.authenticate(...)
метод в среде routing-controllers.
Кто-нибудь может мне это объяснить?
Ответ №1:
Решение, которое я бы выбрал, — это создание вашего собственного промежуточного программного обеспечения, которое будет обрабатывать passport.authenticate()
(посмотрите, как это сделать здесь). Затем вы можете использовать свое собственное промежуточное программное обеспечение с @UseBefore()
decorator.
@Get("/login-sso")
@UseBefore(yourFirstMiddleware)
loginSso() {
// ... something you want to do after passport.authenticate()
}
И аналогичное для второй конечной точки:
@Post("/login-sso/consume")
@UseBefore(yourSecondMiddleware)
loginSso() {
// ... some other action you want to do after
}
Для других решений проверьте документацию используемой вами платформы.
Ответ №2:
При использовании методов PassportJS непосредственно в настройке маршрутизатора функции запроса / ответа / next «волшебным образом» потребляются при закрытии. Поэтому, если вы извлекаете и применяете их в другом классе, вам нужно будет предоставить их явно.
В классе router
...
this.router.get('/login', (req, res, next) => this.authenticate(req, res, next)); // Called by user
this.router.get('/callback', (req, res, next) => this.callback(req, res, next)); // Called by OAuth2 provider
...
/**
* Authenticate the user
* @param req
* @param res
* @param next
*/
private authenticate(req: Request, res: Response, next: NextFunction){
this.logger.debug('Performing authentication');
this.customController.authenticate(req, res, next);
}
/**
* Callback after OAuth2 provider has authenticated the user
* @param req
* @param res
* @param next
*/
private callback(req: Request, res: Response, next: NextFunction){
this.logger.debug('Callback from OAuth provider');
this.customController.callback(req, res, next);
}
В пользовательском контроллере
/**
* Executes the authentication using passportJS
*/
public executeAuthenticate(req: Request, res: Response, next: NextFunction): void {
this.logger.debug('Authenticate using passport');
passport.authenticate('<strategy>', { scope: ['email', 'profile'] })(req, res, next); // <== Here! See that the function is called using the parameters (req,res,next)
}
/**
* Callback after login completion
* @param req
* @param res
* @param next
*/
public callback(req: Request, res: Response, next: NextFunction): void {
this.logger.debug('Callback from oAuth provider');
// Ask passportJS to verify that the user is indeed logged in
passport.authenticate('<strategy>', (err, user, info)=> {
this.logger.debug('Authentication check done');
if (err) {
this.logger.debug('Authentication error');
return next(err);
}
if (!user) {
this.logger.debug('Could not extract user');
return next('Could not find user object');
}
this.logger.debug('Authentication succeeded');
return res.json(user);
})(req, res, next); // <== Here! See that the function is called using the parameters (req,res,next)
}