如何在护照LocalStrategy回调中获取http request.body或request

Zia*_*nur 3 authentication node.js passport-local

只是想在 LocalStrategy 的回调中获取 http 请求或 request.body,正如您在附件中看到的那样,我们像这样编码 new LocalStrategy({ usernameField: 'email', passwordField: 'pwd' },(username: any, password :any,done:any) => { 我们能够获取用户名和密码,但我想获取整个 req.body

  1. 我想获取在登录请求中传递的一些附加信息,并希望将此附加信息存储为创建的会话的一部分。
  2. 我尝试使用护照的 req.logIn() 方法来解决此问题,方法是在 Passport.authenticate('local',callback) 的回调中。
  3. 它有效,但这里的问题是 Passport.serialize 方法被调用两次,因此它创建了两个会话。我想避免创建双重会话。
  4. 因此我认为的解决方案是通过 LocalStrategy 方法获取附加信息。

代码

import UserDetailsRepo from '../../repo/UserDetailsRepo'
import UserDetails from '../../model/UserDetails'
import * as passport from 'passport'
import { Strategy as LocalStrategy } from 'passport-local'
// import JwtConfiguration from './express-jwt-config'
import * as HttpStatus from 'http-status-codes'

class PassportAuth {
    public passport: any;
    constructor() {
        this.passport = passport.use(new LocalStrategy({
            usernameField: 'email',
            passwordField: 'pwd'
          },(username: any, password: any, done: any) => {
            UserDetailsRepo.fetch(username)
                .then(function (userDetails: UserDetails) {
                    if (!userDetails) {
                        return done(null, false, { errorCode: HttpStatus.UNAUTHORIZED, message: 'Incorrect username.' });
                    }
                    if (!userDetails.validatePassword(password)) {
                        return done(null, false, { errorCode: HttpStatus.UNAUTHORIZED, message: 'Incorrect password.' });
                    }
                    return done(null,  userDetails);
                })
                .catch((err: any) => {
                    return done(err);
                })
        }))
        // passport.use(JwtConfiguration.getStrategy())
        passport.serializeUser(function (user, done) {
            if(!user) {
                done({ errorCode: HttpStatus.UNPROCESSABLE_ENTITY,message:'ser' },user)
            } else {
                done(null, user);
            }
        });

        passport.deserializeUser(function (user, done) {
            console.log("Deseriaize User");
            console.log(user);
            done(null, user);
        });
    }
}
export default new PassportAuth().passport;


router.post('/login', passport.authenticate('local'), (req: Request, res: Response, next: NextFunction) => {
            passport.authenticate('local', (err: any, user: UserDetails, info: any) => {
                if (user) {
                    let loginUser = user.checkAttributes(req.body.role, req.body.department);
                    // if (loginUser) {
                        req.logIn(loginUser, function (err) {
                            if (err) {
                                next(err)
                            }
                            next()
                        });
                    // } else {
                    //  next({ errorCode: HttpStatus.UNPROCESSABLE_ENTITY })
                    // }
                } else {
                    next(info)
                }
            })(req, res, next)
        }, (req: Request, res: Response) => {
            res.send(req.body)
            res.end()
        });
Run Code Online (Sandbox Code Playgroud)

Zia*_*nur 7

如果你看下面的代码

this.passport = passport.use(new LocalStrategy({
            usernameField: 'email',
            passwordField: 'pwd',
            passReqToCallback:true
          },(req:any,username: any, password: any, done: any) => {
            UserDetailsRepo.fetch(username)
                .then(function (userDetails: UserDetails) {
                    if (!userDetails) {
                        return done(null, false, { errorCode: HttpStatus.UNAUTHORIZED, message: 'Incorrect username.' });
                    }
                    if (!userDetails.validatePassword(password)) {
                        return done(null, false, { errorCode: HttpStatus.UNAUTHORIZED, message: 'Incorrect password.' });
                    }
                    try {
                        return done(null, userDetails.getLoginUserDetails(req.body.role,req.body.department));
                    } catch (e){
                        return done(null, false, { errorCode: HttpStatus.UNAUTHORIZED, message: e.message } );
                    }                    
                })
                .catch((err: any) => {
                    return done(err);
                })
        }))
Run Code Online (Sandbox Code Playgroud)

passReqToCallback :true 被添加到 LocalStrategy 中,当我们将其设置为 true 时,我们将在 LocalStrategy 的回调函数中获取请求作为第一个参数,即(req :any,username:any,password:any,done:any)

去哪里查看?如果您看到 LocalStrategy 构造函数的代码

declare class Strategy extends PassportStrategy {
    constructor(
        options: IStrategyOptionsWithRequest,
        verify: VerifyFunctionWithRequest
    );
    constructor(options: IStrategyOptions, verify: VerifyFunction);
    constructor(verify: VerifyFunction);

    name: string;
}
Run Code Online (Sandbox Code Playgroud)

上面的代码中有两个主要接口 IStrategyOptionsWithRequestIStrategyOptions


interface IStrategyOptions {
    usernameField?: string;
    passwordField?: string;
    session?: boolean;
    passReqToCallback?: false;
}

interface IStrategyOptionsWithRequest {
    usernameField?: string;
    passwordField?: string;
    session?: boolean;
    passReqToCallback: true;
}

Run Code Online (Sandbox Code Playgroud)

现在很清楚,通过向passReqToCallback传递 true 或 false 值,我们将在 LocalStrategy 的回调中获取请求对象。

为什么将请求作为回调中的第一个参数?如果你看上面的构造函数代码,有两个函数VerifyFunctionWithRequestVerifyFunction。VerifyFunctionWithRequest接口中 第一个参数是req 希望它很清楚......


interface VerifyFunctionWithRequest {
    (
        req: express.Request,
        username: string,
        password: string,
        done: (error: any, user?: any, options?: IVerifyOptions) => void
    ): void;
}

interface VerifyFunction {
    (
        username: string,
        password: string,
        done: (error: any, user?: any, options?: IVerifyOptions) => void
    ): void;
}
Run Code Online (Sandbox Code Playgroud)