在哪里存储以及如何在客户端维护来自 cosmos db 的延续令牌

Posted

技术标签:

【中文标题】在哪里存储以及如何在客户端维护来自 cosmos db 的延续令牌【英文标题】:Where to store and how to maintain the continuation Token from cosmos db at client side 【发布时间】:2020-12-01 12:26:40 【问题描述】:

我计划使用 cosmos db 延续令牌实现分页。我的 api 将返回结果和继续令牌给客户端。我的问题是哪个是存储延续令牌的最佳位置?此外,每个后续请求都会更改令牌?如何维护之前的 continousTokens?

这里显示了我们从哪里获取值,而不是在哪里存储它How to pass\user azure continue token via webAPI Pagination in Cosmos DB using Page Size and Page Number

controller.cs

        [Route("myApps")]
        [HttpGet]
        public async Task<IActionResult> GetAllAppsAsync(string continuationToken, CancellationToken cancellationToken)
        
            var user = this.GetUser();
            var results = await this.appRepository.GetAppsForUserAsync(user, continuationToken, cancellationToken).ConfigureAwait(false);
            var result = this.mapper.Map<AppHeader[]>(results.Value);
            return this.Ok(new KeyValuePair<string, AppDefinitionHeader[]>(results.Key, result));
        
Repository.cs

 public async Task<KeyValuePair<string, IEnumerable<App>>> GetAppForUserAsync(User user,  string continuationToken, CancellationToken cancellationToken)
        
            
            try
            
                FeedOptions queryOptions = new FeedOptions
                
                    MaxItemCount = 2,
                    RequestContinuation = continuationToken
                ;
                string token = string.Empty;
                var query = this.factory.GetClient()
                    .CreateDocumentQuery<AppDefinitionResource>(
                        UriFactory.CreateDocumentCollectionUri(DatabaseName, CollectionName),
                        queryOptions)
                    .AsDocumentQuery();

                List<AppDefinition> results = new List<AppDefinition>();
                while (query.HasMoreResults && results.Count <= 2)
                
                    cancellationToken.ThrowIfCancellationRequested();

                    var response = await query.ExecuteNextAsync<App>(cancellationToken).ConfigureAwait(false);

                    var apps = this.mapper.Map<App[]>(response);
                    results.AddRange(apps);
                    token = response.ResponseContinuation;
                

                return new KeyValuePair<string, IEnumerable<App>>(token, results);
            
           
        

更新:

如何维护之前的continousTokens?

Ex : 如果有 100 条记录并且 pageSize=10 并且 pageNumbers 是 1,2,3,4,5,6,7,8,9,10 并且如果用户在任何页面上随机点击。在那种情况下如何获取所需的记录?或者只是如果我在下面的屏幕截图中放置“上一个”按钮并想要在列表中遍历。

https://i.stack.imgur.com/BMwI2.gif

【问题讨论】:

这取决于您 - 您需要将其返回给 API 的客户端,并公开一种方法,让您的客户端将分页传递回您的 API。 嘿,马丁,刚刚更新了问题,正在将 continuationToken 和结果传递给客户端,以及在后续请求中如何绑定从客户端传递的控制器中的 continuationToken?我不能使用 [FromUri] 因为令牌非常大,而且由于 Get 请求我也不能使用 body。这里的最佳做法是什么? 【参考方案1】:

是的,每个请求的令牌都会更改,因此您可以使用以前的令牌检索以前的页面。

如果您将令牌传递给客户端以保持后端无状态,则不应在 URL 或 URL 查询中发送令牌,因为令牌可能会变得非常大。在客户端中,您可以将令牌保存在内存中。在大多数情况下,没有必要保留令牌,因为令牌应该是短暂的。它应该是短暂的,因为分页结果反映了每个页面请求之间发生的所有更改。


基于 cmets 更新

由于令牌可能很大,它必须在请求正文中传递,这也意味着它不应该是 GET 请求。

另一种解决方案是将令牌存储在具有较小密钥(例如 GUID)在后端(具有一些有限的 TTL)的缓存中,并在后端和客户端之间传递密钥。这样您就可以在 URL 或 URL 查询中传递密钥。但这需要后端保持状态。

【讨论】:

嘿莫,刚刚更新了问题,正在将 continuationToken 和结果传递给客户端,以及在后续请求中如何绑定从客户端传递的控制器中的 continuationToken?我不能使用 [FromUri] 因为令牌非常大,而且我也不能因为 Get 请求而使用 body。这里的最佳做法是什么? @DeepakKothari 我扩展了答案。这能回答你的问题吗? 我使用“POST”请求实现了这个,这里我的疑问是如何维护以前的 continuosTokens?如何维护之前的 continousTokens?例如:如果有 100 条记录并且 pageSize=10 并且 pageNumbers 是 1,2,3,4,5,6,7,8,9,10 并且如果用户在任何页面上随机点击。在那种情况下如何获取所需的记录?或者只是如果我在下面的屏幕截图中放置“上一个”按钮并想要在列表中遍历。 i.stack.imgur.com/BMwI2.gif 不确定您的确切意思,但无论如何这应该在单独的问题中提出。 嘿@Mo,我想向后翻页。我想我需要这样做***.com/questions/52357925/… 或者如果您有任何想法,请告诉我。

以上是关于在哪里存储以及如何在客户端维护来自 cosmos db 的延续令牌的主要内容,如果未能解决你的问题,请参考以下文章

在哪里存储访问令牌以及如何跟踪用户(在 Http only cookie 中使用 JWT 令牌)

我的应用程序需要发送电子邮件,我应该在哪里以及如何存储 SMTP 密码?

如何在 Python 中从 Azure 函数调用 Cosmos DB 存储过程?

Cosmos 中的 AuthZForce FIWARE

如何配置我的 Azure Functions 环境,以便可以在 Python 代码中使用 Cosmos DB 客户端?

在客户端存储 JWT 令牌的位置以及如何保护它? [复制]