我最近使用指南here初始化了Keystone应用。我在代码中碰到的唯一另一件事是在前端添加了一个Next.js应用程序,并更改了mongodb连接字符串以指向我的MongoDB Atlas集群。我在Heroku上部署了此应用程序,它可以连接到数据库,并且一切正常,但是在尝试登录时,单击“登录”后,该按钮会显示加载指示器一秒钟,然后再次显示登录页面。
我已经阅读了文档并尝试放入
config: {
identityField: 'email',
secretField: 'password'
}
在我的authStrategy
定义中,但无济于事。真的不确定从这里还能去哪里。
这是我的Keystone
定义:
const keystone = new Keystone({
name: PROJECT_NAME,
adapter: new Adapter({
mongoUri: 'mongodb+srv://stratus:[email protected]/stratus?retryWrites=true&w=majority',
useNewUrlParser: true
}),
});
// Access control functions
const userIsAdmin = ({ authentication: { item: user } }) => Boolean(user && user.isAdmin);
const userOwnsItem = ({ authentication: { item: user } }) => {
if (!user) {
return false;
}
return { id: user.id };
};
const userIsAdminOrOwner = auth => {
const isAdmin = access.userIsAdmin(auth);
const isOwner = access.userOwnsItem(auth);
return isAdmin ? isAdmin : isOwner;
};
const access = { userIsAdmin, userOwnsItem, userIsAdminOrOwner };
keystone.createList('User', {
fields: {
name: { type: Text },
email: {
type: Text,
isUnique: true,
},
isAdmin: { type: Checkbox },
password: {
type: Password,
},
},
// To create an initial user you can temporarily remove access controls
access: {
read: access.userIsAdminOrOwner,
update: access.userIsAdminOrOwner,
create: access.userIsAdmin,
delete: access.userIsAdmin,
auth: true,
},
});
const authStrategy = keystone.createAuthStrategy({
type: PasswordAuthStrategy,
list: 'User',
config: {
identityField: 'email',
secretField: 'password'
}
});
module.exports = {
keystone,
apps: [
new GraphQLApp(),
// To create an initial user you can temporarily remove the authStrategy below
new AdminUIApp({ enableDefaultRoute: true, authStrategy }),
new NextApp({ dir: 'client'})
],
};
我的Heroku日志中没有看到任何错误。非常感谢您的帮助!
原来,它是内存中的会话存储,根据文档,它不会扩展到单个进程。在生产中,需要通过传递Keystone
的键值对在"session store": <Session Store>
构造函数中进行设置,如图in the docs
正如Daniel指出的那样,内存会话存储无法扩展。为了解决这个问题,我必须将mongoStore附加到会话存储。
这是Keystone v5
const session = require("express-session");
const MongoStore = require("connect-mongo")(session);
const keystone = new Keystone({
name: PROJECT_NAME,
adapter: new Adapter({
mongoUri: process.env.MONGO_URL
}),
onConnect: initialiseData,
cookieSecret: process.env.SESSION_KEY,
secureCookies: false, <-- needed on non-SSL servers
sessionStore: new MongoStore({
url: process.env.MONGO_URL
})
});
connect-mongohttps://www.npmjs.com/package/connect-mongo
express-session https://www.npmjs.com/package/express-session