在 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。尝试更新的答案 @LouiseFinch System.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实现权限控制,实现微服务获取当前用户信息

如何在 websocket 控制器中检索当前登录的用户

从 ASP.NET Core Web API 中的控制器访问用户身份

在 spring + angular 中获取当前登录用户

如何使用 JWT 令牌在 .NET Core API 中检索当前用户数据?

教你简单实现小程序的一键登录、当前用户、用户安全功能