Javascript 如何在启动时将持久会话初始化到passport/会话文件存储中?
此express应用程序使用passport向azure进行身份验证。当用户进行身份验证时,用户数据将保存到内存存储中,然后将其写入会话存储中 当express应用程序重新启动时,它将从会话存储中加载以前保存的用户数据。但是,passport不能识别以前经过身份验证的用户,需要他们重新进行身份验证。这是一个问题,因为该应用程序仍在开发中,需要频繁重新启动 我希望应用程序在重新启动后识别以前经过身份验证的用户。Javascript 如何在启动时将持久会话初始化到passport/会话文件存储中?,javascript,node.js,session,passport.js,Javascript,Node.js,Session,Passport.js,此express应用程序使用passport向azure进行身份验证。当用户进行身份验证时,用户数据将保存到内存存储中,然后将其写入会话存储中 当express应用程序重新启动时,它将从会话存储中加载以前保存的用户数据。但是,passport不能识别以前经过身份验证的用户,需要他们重新进行身份验证。这是一个问题,因为该应用程序仍在开发中,需要频繁重新启动 我希望应用程序在重新启动后识别以前经过身份验证的用户。 更新:经过进一步研究,我发现会话由express session包管理。我已将会话文
更新:经过进一步研究,我发现会话由
express session
包管理。我已将会话文件存储
包添加到代码中,并将其配置为保存会话。这些会话仍然不会持续
这个应用程序就是从这个开始的。它将用户数据序列化并反序列化到内存存储中,我添加了代码来持久化数据。但存储的用户数据与浏览器中存储的会话密钥之间存在断开连接 应用程序使用用户的
oid
作为键来存储用户,如下所示:
{
"1aa31bba-xxxx-xxxx-xxxx-xxxx": {
"profile": {
"sub": "_v3k8L5PkIREMis1in9IF3SucjEQqxRxThsoK35rBZQ",
"oid": "1aa31bba-xxxx-xxxx-xxxx-xxxx",
...
}
}
}
但是,浏览器的会话cookie不是oid:
"connect.sid":"s:cd957624-72ba-4552-893d-8fd59bbce31e.Gt87eHx0WjkKXOKeq6oDvsw35BZZ+6ZQ6p0c3dwjRTE"
cookieconnect.sid
是浏览器中存储的唯一cookie。每次用户重新验证时,cookie的值都会更改。此cookie不会写入用户文件或会话文件。这就是我不知道如何解决的脱节
在启动之前的会话时,初始化会话文件存储的正确方法是什么?
这是申请者的护照代码
var passport = require('passport');
var OIDCStrategy = require('passport-azure-ad').OIDCStrategy;
var FileStore = require('session-file-store')(session); // added to test FileStore
require('dotenv').config();
var users = {};
var userStore = require('userStore');
users = userStore.load();
// Passport calls serializeUser and deserializeUser to manage users
passport.serializeUser(function (user, done) {
// Use the OID property of the user as a key
users[user.profile.oid] = user;
userStore.save(users);
done(null, user.profile.oid);
});
passport.deserializeUser(function (id, done) {
done(null, users[id]);
});
const oauth2 = require('simple-oauth2').create({
client: {
id: process.env.OAUTH_APP_ID,
secret: process.env.OAUTH_APP_PASSWORD
},
auth: {
tokenHost: process.env.OAUTH_AUTHORITY,
authorizePath: process.env.OAUTH_AUTHORIZE_ENDPOINT,
tokenPath: process.env.OAUTH_TOKEN_ENDPOINT,
}
});
async function signInComplete(iss, sub, profile, accessToken, refreshToken, params, done) {
if (!profile.oid) {
return done(new Error("No OID found in user profile."));
}
try {
const user = await graph.getUserDetails(accessToken);
if (user) {
// Add properties to profile
profile['email'] = user.mail ? user.mail : user.userPrincipalName;
}
} catch (err) {
return done(err);
}
// Create a simple-oauth2 token from raw tokens
let oauthToken = oauth2.accessToken.create(params);
// Save the profile and tokens in user storage
users[profile.oid] = { profile, oauthToken };
return done(null, users[profile.oid]);
}
passport.use(new OIDCStrategy(
{
identityMetadata: `${process.env.OAUTH_AUTHORITY}${process.env.OAUTH_ID_METADATA}`,
clientID: process.env.OAUTH_APP_ID,
responseType: 'code id_token',
responseMode: 'form_post',
redirectUrl: process.env.OAUTH_REDIRECT_URI,
allowHttpForRedirectUrl: true,
clientSecret: process.env.OAUTH_APP_PASSWORD,
validateIssuer: false,
passReqToCallback: false,
scope: process.env.OAUTH_SCOPES.split(' ')
},
signInComplete
));
app.use(session({
secret: process.env.SESSION_SECRET_KEY,
store: new FileStore({}), // added to test FileStore
genid: uuid,
resave: true, // false, // changed to test FileStore
saveUninitialized: true, // false, // changed to test FileStore
unset: 'destroy'
}));
app.use(passport.initialize());
app.use(passport.session());
下面的更改应该会有所帮助,因为我不确定“sessionStore”是在内存中创建的,一旦重新启动应用程序,用户列表将删除并再次注册
var passport=require('passport');
var OIDCSTRAGEY=require('passport-azure-ad')。OIDCSTRAGEY;
require('dotenv').config();
//理想情况下,这需要用DB替换
var用户=[];
//如果存在DB,则不需要这样做
让getUser=(id)=>{
for(让index=0;index{
for(让index=0;index{
if(profile.oid){
if(checkIfUserExists(profile.oid)){
//getUser和return user,如果DB此部分将更改
let user=getUser(profile.oid);
让userDetails={};
试一试{
userDetails=wait graph.getUserDetails(accessToken);
}捕获(错误){
返回完成(错误);
}
user.userDetails=userDetails;
user.oauthToken=oauth2.accessToken.create(参数);
返回完成(空,用户);
}否则{
//创建一个新用户并返回用户,将在db就位时更改
让userDetails={};
试一试{
userDetails=wait graph.getUserDetails(accessToken);
}捕获(错误){
返回完成(错误);
}
//根据当前代码,用户结构保留了我的最佳状态
让newUser={
id:profile.oid,
userDetails:userDetails,
简介:简介,,
oauthToken:oauth2.accessToken.create(参数)
};
push(newUser);
返回完成(null,newUser)
}
}否则{
返回完成(新错误(“在用户配置文件中找不到OID”);
}
});
}
passport.使用(新策略)(
{
identityMetadata:“${process.env.OAUTH_AUTHORITY}${process.env.OAUTH_ID_METADATA}”,
clientID:process.env.OAUTH_APP_ID,
responseType:'代码id_令牌',
responseMode:“表单发布”,
重定向URL:process.env.OAUTH_REDIRECT_URI,
allowHttpForRedirectUrl:true,
clientSecret:process.env.OAUTH_APP_密码,
验证者:错,
passReqToCallback:false,
作用域:process.env.OAUTH_SCOPES.split(“”)
},
完成
));
//有关此部分,请参阅护照文档
应用程序使用(会话)({
机密:process.env.SESSION\u secret\u密钥,
精灵:uuid,
resave:false,//一旦有了存储,就更改为true
saveUninitialized:false//一旦有了存储,就更改为true
}));
app.use(passport.initialize());
app.use(passport.session());
作为参考,根本原因是
user.oauthtoken
对象是类AuthToken
的实例。当用户被序列化到存储器时,json只记录obj
passport.deserializeUser(function (id, done) {
done(null, users[id]);
});
passport.deserializeUser(function (id, done) {
let user = users[id];
if( user.oauthToken.constructor.name !== "AccessToken" ) {
user.oauthToken = oauth2.accessToken.create(user.oauthToken.token);
}
done(null, user);
});