在 web api 控制器中获取当前登录的用户
Posted
技术标签:
【中文标题】在 web api 控制器中获取当前登录的用户【英文标题】:Getting current logged on user in web api controller 【发布时间】:2020-01-07 05:16:31 【问题描述】:我正在尝试在 Web API 控制器中检索当前登录的用户详细信息以创建用户配置文件页面。
我已经创建了方法,但用户在代码中不断返回 null,如下所示。这在我的 MVC 控制器中工作正常,但在 Web API 控制器中它会引发错误。
[HttpGet]
public IActionResult userProfile()
if (ModelState.IsValid)
var user = _userManager.Users.First(x => x.Email == User.Identity.Name);
return Ok(new UserViewModel
Id = user.Id,
UserName = user.Email,
FirstName = user.FirstName,
LastName = user.LastName
);
else
return BadRequest(ModelState);
更新
[HttpGet]
[Authorize(Roles = "Client, Administrator")]
public IActionResult userProfile()
string baseUrl = "https://localhost:5001";
HttpClient client = new HttpClient();
client.BaseAddress = new Uri(baseUrl);
var contentType = new MediaTypeWithQualityHeaderValue("application/json");
client.DefaultRequestHeaders.Accept.Add(contentType);
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", HttpContext.Session.GetString("token"));
UserViewModel userModel = new UserViewModel();
HttpResponseMessage response = client.GetAsync("https://localhost:5001/api/UserAPI").Result;
string stringData = response.Content.ReadAsStringAsync().Result;
userModel = JsonConvert.DeserializeObject<UserViewModel>(stringData);
return View(userModel);
错误信息:
System.InvalidOperationException: '序列不包含任何元素
【问题讨论】:
调用 API 时传递了什么? @SimonPrice 请查看我在 MVC 控制器中获取方法的更新问题 【参考方案1】:我假设您使用的是 WebAPI 2。
尝试以下方法:
var user = _userManager.GetUser(HttpContext.User);
或
var user = _userManager.FindById(User.Identity.GetUserId());
【讨论】:
我使用过 Microsoft.AspNetCore.Identity;在课堂上,但仍然没有拿起它。我也试过 RequestContext.Principal 但找不到, @LouiseFinch 您使用的是 .NET Core。尝试更新的答案 @LouiseFinchSystem.Web.HttpContext.Current.User.Identity.GetUserId();
返回什么?
它说 HttpContext 确实包含 Current 的定义【参考方案2】:
而不是 .First() 将其更改为 .FirstOrDefault()
【讨论】:
检查您的情况是对还是错。 User.Identity.Name 有值【参考方案3】:API 是无状态的,这意味着没有登录用户或会话的概念。这是因为每个请求都是唯一的、独立的,并且包含提供响应所需的所有信息。
API 无法知道谁在发送请求,可能有 10k 人同时发送请求,那么究竟谁“登录”了?
因此,如果您想加载用户配置文件,请将用户 ID 作为参数发送,例如:
[HttpGet]
public IActionResult userProfile(string userEmail)
if ( !string.IsNullOrEmpty (userEmail) ) ..... etc etc
var user = _userManager.Users.First(x => x.Email == userEmail);
return Ok(new UserViewModel
Id = user.Id,
UserName = user.Email,
FirstName = user.FirstName,
LastName = user.LastName
);
附带说明,如果您没有任何输入参数,或者输入是原始类型(例如字符串或 int),则 ModelState.IsValid 不会执行任何操作。仅当您的模型类填充了正确的规则时,才使用 ModelState.IsValid。
在我的情况下,我实际上可以用一个类替换字符串
public class UserProfileRetrieveModel
[Required]
public string UserEmail get;set;
那我可以做:
[HttpGet]
public IActionResult userProfile(UserProfileRetrieveModel model)
if (ModelState.IsValid)
var user = _userManager.Users.First(x => x.Email == model.UserEmail);
//etc
else
return BadRequest(ModelState);
---问题更新后
所以看起来您有一个客户端应用程序并从中调用 API。 我上面所说的一切仍然适用,只需在调用 API 之前填充您拥有的数据。
例子:
public IActionResult userProfile()
//removed code we don't care about
string userEmail = "";// get your user email here in the MVC controller
//populate it in the api url.
//you might need to URL encode it since it will contain dots and @
string apiUrl = "https://localhost:5001/api/UserAPI/userEmail";
HttpResponseMessage response = client.GetAsync(apiUrl).Result;
您无需在 API 中解决任何问题,只需将您需要的所有内容从 MVC 控制器传递给 API。
现在,抛开这一切,你有大量的异步问题。该部分需要工作,尽管它与问题无关。
【讨论】:
这适用于 Post 方法,但不适用于 get 方法,因为我希望使用登录用户的详细信息填充输入表单 这不会改变任何东西,请参阅我的更新答案【参考方案4】:从错误消息看来,您正在尝试从空序列中检索元素。因此请检查您是否有数据。并尝试使用 .FirstOrDefault()。
【讨论】:
以上是关于在 web api 控制器中获取当前登录的用户的主要内容,如果未能解决你的问题,请参考以下文章
Springboot security oauth2 jwt实现权限控制,实现微服务获取当前用户信息
从 ASP.NET Core Web API 中的控制器访问用户身份