当前位置: 首页 > 知识库问答 >
问题:

node.js无状态/无Cookie会话API身份验证

彭风华
2023-03-14

我正在构建一个API,并试图在多个上下文中解决身份验证问题。

API需要为我们创建和部署的客户端应用程序提供服务,并使用密码处理经过身份验证的请求。在每个请求中都发送密码并不是一个好主意,因此首先点击登录endpoint并获得会话ID更有意义。问题中的webapp是用AngularJS编写的,应该在localStorage中跟踪自己的会话,以减轻会话劫持并消除对cookie的依赖以跟踪会话。

webapp需要在每个请求中发送会话标识符,并且当前在请求正文中这样做。它很容易碎片化,并与API紧密耦合。我更愿意以一种方式传递所有身份验证信息--最好是通过一个头--而不是在分布在请求主体、url和头上的多个不同字段中。

雷迪斯当然很棒。会话存储是直接的和自动垃圾收集。不幸的是,redis中的会话很难管理:我不能轻易地撤销给定用户的所有会话。通过将会话存储在真正的redis-datastructure(而不是全局密钥空间)中来添加该功能,就会删除添加键控TTL的功能。我目前的解决方案是在MongoDB用户集合中存储会话列表,并在会话activity(例如登录/注销)上垃圾收集过期会话。

会话与connect-redis模块一起存储在redis中,但当它们与每个请求一起发送时,它们并不包含在cookie中。目前,我有一小块中间件,它从请求体中取出会话标识符,并将其放入req.cookies对象中。

var express = require('express');
var RedisStore = require('connect-redis')(require('connect'));

var app = express();
app.use(function(req, res, next) {
  req.cookies = {session: req.body.session};
});
app.use(express.session({
  store: new RedisStore({
    client: redisClient,
    prefix: 'session:'
  }),
  key: 'session',
  secret: 'all mine'
});

这种方法工作得很好,只是express.session在express响应时最终设置cookie,而这不是所希望的行为。

我如何在Express的上下文中正确地设置它?

我们的API还应该支持第三方应用程序的API密钥,以获得对我们系统的有限和受控访问。我所知的最常见的机制是将API密钥分发给感兴趣的开发人员,并让开发人员将API密钥作为请求的一部分传入。这会遇到与会话/密码身份验证相同的困境:每个API都希望在请求的不同部分中提供API密钥,从主体到url再到报头。

虽然我们不打算在初始版本时支持OpenAuth和OpenID等开放身份验证标准,但我们希望创建一个框架,在该框架中添加所述标准是直接的。其中一部分可以是统一授权凭据如何传递给API,就像会话/密码和API密钥支持的身份验证一样。

另一个问题是自定义HTTPauthorization头是一个好主意,还是自定义头是一个更好的主意。

为了支持RESTful API的CRUD范例,不在正文中提供身份验证信息是有意义的,因为这会将所有API请求限制为POST请求,而CRUD建议使用各种HTTP方法。

两件事:

  1. 我们如何使用connect-redis这样的模块而不使用基于cookie的会话。
  2. 应如何配置身份验证信息以获得最大的灵活性和互操作性?

共有1个答案

郗河
2023-03-14

正如所给出的,这个问题是无法回答的。会话状态。因此,您不能无状态地实现会话。

如果您实际上想要无状态身份验证,那么您就不能有会话,应该使用HTTP身份验证机制。

如果实际需要会话,但不希望在Cookie头中传输状态令牌,则应该使用OAuth机制,该机制允许使用授权头或请求参数来保存协商后的状态令牌。

我们确实希望创建一个框架,在该框架中添加所述标准是直接的

最简单和最好的方法是首先使用它们。不要重新发明轮子。OAuth2被设计成可以在多个用例中轻松实现,并且如果您需要更多,它有自己的扩展机制。

 类似资料:
  • null 一些重要注意事项: 我们有传输安全性(HTTPS及其最好的朋友); 在窗帘后面,web应用程序代表当前用户将大量操作委托给外部服务(这些系统确实将Bob识别为其用户之一)--这意味着我们必须将Bob的凭据转发给它们。 现在,我们如何(在每个请求上)对Bob进行身份验证?哪一种方法会是实施这样的事情的合理方法呢? null null 非常感谢您花时间阅读以下内容:)

  • 一切工作都很正常,只是随机/偶尔地,尽管用户登录了,会话超时发生,系统注销了用户,尽管令牌有7天的有效期。 所以我决定尝试使系统没有任何会话而无状态。为此,我使用了以下命令: 根据禁用主题状态会话存储 然而,现在我根本无法登录。我得到了 我还没有找到任何完整的会话少四郎的例子。对我的代码有什么建议让它工作吗??我一定是错过了什么,但我不知道是什么。 为什么禁用会话后MyRealm无法从Userna

  • 当应用程序依赖于无状态身份验证(使用类似HMAC的东西)时,是否有必要使用CSRF保护? 示例: > 我们有一个单页应用程序(否则我们必须在每个链接上添加令牌:。 此内标识将用于访问诸如之类的受限URL。 令牌将始终在HTTP头内传输。 没有Http会话,也没有cookie。

  • 需要一些帮助!!我对Drools中的有状态和无状态会话没有清晰的理解。我正在努力理解这一点,所以尝试了一个例子。 我在drools6.5版本上使用有状态和无状态会话测试了下面的drl,在这两种情况下都得到了相同的输出。根据我对无状态会话的理解,它应该只执行第一条规则,当应用程序对象在第一条规则中被修改时,第二条规则不应该被激活(“有效期”)。附加源代码。感谢您在这方面的帮助。

  • 我试图理解为什么JWT认证是无状态的。在有状态认证中,会有一个会话id。这里有一张JWT的代币,上面有签名。所以身份验证服务器发布JWT令牌,但是我可以说后续请求中JWT令牌的验证是由endpoint服务器(应用服务器)而不是身份验证服务器来完成的吗?我相信这是可能的,因为JWT是用截止日期(还有一些其他信息)签名的,并且认证服务器的公共证书对所有endpoint服务器都是可用的。 因此,认证服务

  • 我是EJB的新手,最近开始研究EJB(3.0)。我已经使用Java6年了,但以前从未使用过EJB。至少可以说,整个EJB业务的复杂性让我不知所措。我不明白我可以在哪里实际应用一些概念。 在理解无状态会话bean后,我想到的一个问题是,你能不能不要总是用一个没有本地成员的类的共享实例来替换无状态会话bean(实际上使其无状态)?我了解到正在为无状态会话bean进行实例池。如果没有状态,就不能简单地使