【问题标题】:OAuth 2.0 authorization performance in postgrespostgres 中的 OAuth 2.0 授权性能
【发布时间】:2013-11-14 16:37:53
【问题描述】:

我正在开发一个 RESTful API,并且我已经实现了 OAuth 2.0 授权。

我的所有客户端都通过 SSL 发出请求,并在 Authorization 标头中传递不记名令牌:

Authorization: Bearer sdflksd3r4823vgbyerge

目前我在 Postgres 中保存访问令牌和刷新令牌,因此在每个请求中服务器都必须连接到数据库并执行 SELECT 查询。 'tokens' 表包含大约一百万行,所以 性能不是很好,即使该表被索引...我也认为在每个请求上检查令牌有效性是相当浪费的时间。

我们的令牌现在只是随机的数据字节。我们考虑使用自编码令牌,以便无需数据库查找即可解码和验证令牌,但问题是令牌必须对用户可撤销,因此这不是解决方案。

我有什么选择?

我正在考虑使用 Redis 代替 Postgres:读取速度应该更快。 另一种选择可能是检查令牌有效性,将响应缓存在 Memcached 中 15 分钟,因此后续请求不需要数据库查找。

有什么想法吗?

【问题讨论】:

  • “性能不是很好”这句话实际上并没有告诉我们太多信息。您什么时候查看令牌?为什么服务器连接到数据库只是为了这个查询?不过,像 memcache 这样的东西非常适合检查身份验证令牌。
  • 嗨@RichardHuxton 在实施oauth 之前对我的api 的“典型请求”的响应时间为0.200 秒......现在相同的请求大约需要0.800 秒。显然,这些响应时间还不错,还可以……但我至少想尝试减少它们,所以我想也许 postgres 不是存储令牌的最佳解决方案……
  • 600ms 对于简单的查询来说听起来不合适。不过不能肯定地说,因为您没有提供任何硬数据或设置的详细信息。如果您有一个每年 5 美元的盒子在与您的应用程序不同的大陆上运行,那么它会非常快。
  • @RichardHuxton 我正在使用 ec2 微实例,数据库与应用程序服务器位于同一台机器上

标签: api security postgresql rest oauth


【解决方案1】:

我试着轻轻地推敲一些真实的数字。由于您不准备说出您的“ec2 微型实例”在可用 GHz/RAM/磁盘 I/O 方面的实际情况,我们将不得不以另一种方式尝试。

CREATE TABLE tokens(tok text, username text);
INSERT INTO tokens SELECT md5(i::text), 'User number ' || i FROM generate_series(1,1000000) i;
SELECT * FROM tokens WHERE username LIKE '%01' LIMIT 19;
-- Now check the timings on some of returned tokens
EXPLAIN ANALYSE SELECT username FROM tokens WHERE tok = '38b3eff8baf56627478ec76a704e9b52';
                                                 QUERY PLAN                                                      
---------------------------------------------------------------------------------------------------------------------
 Index Scan using tokens_pkey on tokens  (cost=0.42..8.44 rows=1 width=18) (actual time=0.099..0.101 rows=1 loops=1)
   Index Cond: (tok = '38b3eff8baf56627478ec76a704e9b52'::text)
 Total runtime: 0.133 ms
(3 rows)

如您所见 - 我的运行速度如此之快,以至于时间可能毫无意义。如果我在乎的话,我会从 10 个并行进程中运行 10000 个,并随机等待。我没有 - 它不到 1 毫秒,甚至在我期望的最慢的虚拟机上

那么 - 您的应用程序有问题吗?不能说 - 你没有提供细节。

是你的框架吗?不能说 - 你不会说。

是连接时间吗?说不出来……

是查询本身吗?说不出来……

不过,PostgreSQL 使用索引从 tiny 100 万行的表中读取单行的问题并非如此。

祝你好运!

【讨论】:

  • 感谢您的帮助,我会再次检查我的代码并发布任何更新!
  • 嗨@Richard-Huxton 我终于解决了这个问题:错误出在应用程序服务器中,而不是在 Postgres 查询中!我现在可以在不到 3 毫秒的时间内从 200 万个表中提取一行。所以 Postgres 的性能不再是问题。现在....回到原来的问题!这是正确的做法吗?每次客户端发出请求时都在数据库上执行查询吗?将查询结果缓存在 memcache 中是否有意义?或者可能根本不使用 db 而是使用 nosql ?谢谢你的帮助:)
  • 做最简单的事情。查询数据库直到出现问题,然后添加一个简单的缓存。除非您需要,否则拥有两个数据库系统毫无意义。
【解决方案2】:

请注意,令牌上应该有一个索引,Richard 的响应省略了该索引。在创建索引之前,我的查询运行时间约为 200 毫秒。创建索引后,它下降到 0.1 毫秒。 (对不起,我会直接评论他的帖子,但我的分数不够高)。

【讨论】:

    猜你喜欢
    • 2014-03-30
    • 2012-06-19
    • 1970-01-01
    • 1970-01-01
    • 2012-05-31
    • 2013-10-05
    • 2014-07-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多