Keystonejs 6 使用 AuthenticateUserWithPassword 突变从外部前端服务器进行身份验证

问题描述 投票:0回答:1

我正在构建一个具有不同前端的解耦 keystonejs (keystonejs 6) 应用程序,它将使用其 graphql api 从主 keystonejs 实例中提取和推送数据。

我已经设置了访问控制来满足我的需求,并且通过 AdminUI 一切正常,但是当我尝试从外部前端之一执行登录时,在 keystone 实例上没有创建任何会话。

我正在启动突变

AuthenticateUserWithPassword
,它返回会话令牌(因此登录本身正在工作)并在浏览器中设置
keystonejs-session
cookie。我还尝试在
fetch()
请求标头中手动设置此 cookie 并执行查询,但我的外部前端不允许这样做。

mutation AuthenticateUserWithPassword($email: String!, $password: String!) {
  authenticateUserWithPassword(email: $email, password: $password) {
    ... on UserAuthenticationWithPasswordSuccess {
      sessionToken
      item {
        email
      }
    }
    ... on UserAuthenticationWithPasswordFailure {
      message
    }
  }
}

有趣的是,如果我从前端登录并返回 AdminUI,我已登录并可以执行经过身份验证的查询,并且如果我在 AdminUI 上执行任何操作时检查 context.session,我就有一个会话对象,但是当我从外部前端执行任何操作时,会话为空(但我使用相同的 cookie)


从 AdminUI 发出请求时的会话日志,例如

session:  {
  listKey: 'User',
  itemId: '1234567890a123445656',
  data: {
    id: '1234567890a123445656',
    name: 'myUserName',
    createdAt: 'whateverdate'
  }
}

从外部前端发出请求时的会话日志,例如

session:  undefined

除了

keystonejs-session
cookie 之外,我还必须在来自外部前端的查询的标头中发送任何其他内容,以使 keystonejs 识别我经过身份验证的用户并使用该会话吗?

node.js authentication session graphql keystonejs
1个回答
0
投票

好吧,一如既往,在解决这个问题几天后,我只需将其写在 StackOverflow 中,然后一个新想法就出现在我的脑海中。

在尝试了 Keystonejs 文档中的所有内容之后,我刚刚开始调试他们的源代码,似乎有一个带有标准标头的未记录的身份验证功能:

authorization: Bearer + <token>

幸运的是,我刚刚为不同的机制开发了自定义承载身份验证,但我不知道 keystone 正在检查该标头中的某些内容。

不仅要查看它,而且如果存在持有者,会话 cookie 也会被忽略:

const token = bearer || cookies[cookieName];

(来自

node_modules/@keystone-6/core/session/dist/keystone-6-core-session.cjs.dev.js

 async get({
   context
 }) {
  var _context$req$headers$;
  if (!(context !== null && context !== void 0 && context.req)) return;
  const cookies = cookie__namespace.parse(context.req.headers.cookie || '');
  const bearer = (_context$req$headers$ = context.req.headers.authorization) === null || _context$req$headers$ === void 0 ? void 0 : _context$req$headers$.replace('Bearer ', '');
  const token = bearer || cookies[cookieName];
  if (!token) return;
  try {
    return await Iron__default["default"].unseal(token, secret, ironOptions);
  } catch (err) { }
},

所以,这个故事的寓意是:如果存在会话 cookie,切勿使用 Bearer 令牌,或者至少在使用 Keystonejs 时不要这样做

© www.soinside.com 2019 - 2024. All rights reserved.