passport 的序列化解析
// serializeUser 執(zhí)行在 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);
};
源碼
通過自執(zhí)行函數(shù),注入0嗡呼。 每次循環(huán)執(zhí)行之前壓入的執(zhí)行序列化函數(shù) layer施戴。
分離了 執(zhí)行序列化 和 序列化函數(shù)反浓。這樣避免了變量的污染。
// 以下代碼 通過 session 獲取到 session 信息的時候赞哗,會執(zhí)行 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();
};
}