如何使用存储在会话存储中的访问令牌使用 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 调用?的主要内容,如果未能解决你的问题,请参考以下文章