passport 的序列化解析
// serializeUser 执行在 passport 的 认证阶段。
Authenticator.prototype.serializeUser = function(fn, req, done) {
if (typeof fn === 'function') {
return this._serializers.push(fn);
}
// private implementation that traverses the chain of serializers, attempting
// to serialize a user
var user = fn;
// For backwards compatibility
if (typeof req === 'function') {
done = req;
req = undefined;
}
var stack = this._serializers;
(function pass(i, err, obj) {
// serializers use 'pass' as an error to skip processing
if ('pass' === err) {
err = undefined;
}
// an error or serialized object was obtained, done
if (err || obj || obj === 0) { return done(err, obj); }
var layer = stack[i];
if (!layer) {
return done(new Error('Failed to serialize user into session'));
}
function serialized(e, o) {
pass(i + 1, e, o);
}
try {
var arity = layer.length;
if (arity == 3) {
layer(req, user, serialized);
} else {
layer(user, serialized);
}
} catch(e) {
return done(e);
}
})(0);
};
源码
通过自执行函数,注入0。 每次循环执行之前压入的执行序列化函数 layer。
分离了 执行序列化 和 序列化函数。这样避免了变量的污染。
// 以下代码 通过 session 获取到 session 信息的时候,会执行 deserializeUser
// refactor passport session with koa middleware for performance
// https://github.com/jaredhanson/passport/blob/master/lib/strategies/session.js
function session() {
return async function passportSession(ctx, next) {
const req = ctx.req;
let sessionUser;
if (req._passport.session) {
sessionUser = req._passport.session.user;
}
if (sessionUser || sessionUser === 0) {
const user = await ctx.app.passport.deserializeUser(ctx, sessionUser);
if (!user) {
req._passport.session.user = undefined;
} else {
req[ctx.app.passport._userProperty] = user;
}
}
return next();
};
}
网友评论