如何使用存储在会话存储中的访问令牌使用 HttpClient 进行 Web api 调用?

Posted

技术标签:

【中文标题】如何使用存储在会话存储中的访问令牌使用 HttpClient 进行 Web api 调用?【英文标题】:How to use access token stored in session storage for doing web api call using HttpClient? 【发布时间】:2020-03-02 14:44:41 【问题描述】:

我已使用 ajax 调用完成登录,并使用以下代码将访问令牌存储在会话存储中。

        $('#btnLogin').click(function () 
            $.ajax(
                url: 'http://localhost:59983/token',
                method: 'POST',
                contentType: 'application/json',
                data: 
                    username: $('#txtUsername').val(),
                    password: $('#txtPassword').val(),
                    grant_type: 'password'
                ,
                success: function (response) 
                    sessionStorage.setItem("accessToken", response.access_token);
                    console.log("Success!!!!");
                    alert("Login Successful");
                ,
                error: function (jqXHR) 
                    console.log("Failed!!!!");
                    $('#divErrorText').text(jqXHR.responseText);
                    $('#divError').show('fade');
                
            );
        );

现在登录后,我想使用存储的访问令牌通过控制器方法中的 HttpClient 执行 api 调用。我不知道如何传递存储的访问令牌来进行 api 调用。 以下代码是我编写的使用 HttpClient 进行 api 调用的代码。

 using (var client = new HttpClient())
        
            client.BaseAddress = new Uri("http://localhost:59983/api/flight");
            client.DefaultRequestHeaders.Add("Authorization", "Bearer " + accessToken);
            var responseTask = client.GetAsync("flight");
            responseTask.Wait();
            var result = responseTask.Result;
            if (result.IsSuccessStatusCode)
            
                var readTask = result.Content.ReadAsAsync<IList<tblFlight>>();
                readTask.Wait();
                flights = readTask.Result;
            
            else
            
                flights = Enumerable.Empty<tblFlight>();
                ModelState.AddModelError(string.Empty, "Server error. Please contact administrator.");
            
        

请建议我如何使用存储的访问令牌?

【问题讨论】:

sessionStorage.getItem('accessToken');这是从会话存储中获取值的方法 它会在asp.net mvc项目的控制器方法中工作吗? 【参考方案1】:

当我们处理诸如会话存储或本地存储之类的网络存储时,我们在客户端使用 javascript、jquery 等进行处理。这些存储项无法在服务器端代码中访问。它们仅限于您的本地浏览器,可以从浏览器上运行的客户端代码访问。 现在,对于您的情况,我认为您可以在服务器端进行会话。您在本地存储中设置值的点,而不是在那里对服务器上的任何 actionresult 函数进行 ajax 调用并在会话中设置值。稍后在服务器端获取它。同样,如果您想要该值客户端,则需要再次进行 ajax 调用并从控制器中的服务器端函数获取它。

【讨论】:

【参考方案2】:

好的,所以如果我理解正确,您可以登录并创建一个令牌,然后从您的 MVC 控制器调用 API 端点并为此使用存储的令牌。

您发布的代码似乎是您的 MVC 控制器中存在的代码。

 using (var client = new HttpClient())
        
            //here retrieve the token from where you stored it
            string accessToken = "whatever";


            client.BaseAddress = new Uri("http://localhost:59983/api/flight");
            client.DefaultRequestHeaders.Add("Authorization", "Bearer " + accessToken);
            var responseTask = client.GetAsync("flight");
            responseTask.Wait();
            var result = responseTask.Result;
            if (result.IsSuccessStatusCode)
            
                var readTask = result.Content.ReadAsAsync<IList<tblFlight>>();
                readTask.Wait();
                flights = readTask.Result;
            
            else
            
                flights = Enumerable.Empty<tblFlight>();
                ModelState.AddModelError(string.Empty, "Server error. Please contact administrator.");
            
        

现在,如果您直接从 javascript 调用 API 端点,那么理论上您需要将其提供给您的客户端。您可以做的是将令牌也存储在客户端存储中,以便您可以在需要时检索它,我可以看到您已经在客户端执行此操作。

如果您在 MVC 控制器中需要它,则从会话中获取它并将其传递到您的 API 端点。在这种情况下,您可以使用初始的额外调用,无论如何您都会在客户端获取令牌,因此之后只需调用额外的 MVC 端点,将令牌传递给它并将其保存在会话中。如果您需要,这种方式可以在客户端和后端都有它。

MVC 和 Web API 组合有点像对所有东西的混蛋。原因是 MVC 显然可以访问 Session,而 Web API 应该是无状态的,因此没有 Session 访问。理论上,作为 MVC 应用程序一部分的 Web API 端点可以访问 Session 对象,尽管我会避免这样做。我更喜欢将 Web API 作为一个完全独立的项目,但我知道这并不总是可行的。

【讨论】:

以上是关于如何使用存储在会话存储中的访问令牌使用 HttpClient 进行 Web api 调用?的主要内容,如果未能解决你的问题,请参考以下文章

为命令存储访问和刷新令牌

在 Flask 会话中存储 oAuth 状态令牌

如何在 Angular 8 中存储 jwt 令牌之类的数据?是不是有另一种使用本地存储或会话存储安全存储的方法?

如何使用存储在HttpOnly Cookie中的令牌注销

从SSO中的多个系统注销(单点登录)

Oauth2令牌 - 我可以将令牌存储在会话中