Blazor WASM中如何对当前已认证用户的账户信息执行CRUD操作?
服务端API实现(核心安全逻辑)
所有接口必须添加[Authorize]特性鉴权,用户身份完全从服务端的认证上下文获取,不接受任何前端传递的用户标识参数,从根源避免信息冒用。
using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Identity; using Microsoft.AspNetCore.Mvc; using System.Security.Claims; [ApiController] [Route("api/[controller]")] [Authorize] public class UserProfileController : ControllerBase { private readonly UserManager<IdentityUser> _userManager; public UserProfileController(UserManager<IdentityUser> userManager) { _userManager = userManager; } // 查询当前用户信息接口 [HttpGet] public async Task<IActionResult> GetProfile() { // 直接从服务端Claims取用户ID,完全不依赖前端传参 var userId = User.FindFirstValue(ClaimTypes.NameIdentifier); var user = await _userManager.FindByIdAsync(userId); if (user == null) return NotFound(); return Ok(new { user.Email, user.PhoneNumber, // 如果你扩展了IdentityUser的自定义字段,此处对应返回即可 // FirstName = user.FirstName, // LastName = user.LastName }); } // 更新当前用户信息接口 [HttpPut] public async Task<IActionResult> UpdateProfile([FromBody] UpdateProfileRequest request) { var userId = User.FindFirstValue(ClaimTypes.NameIdentifier); var user = await _userManager.FindByIdAsync(userId); if (user == null) return NotFound(); user.PhoneNumber = request.PhoneNumber; // user.FirstName = request.FirstName; // user.LastName = request.LastName; var updateResult = await _userManager.UpdateAsync(user); if (updateResult.Succeeded) return NoContent(); return BadRequest(updateResult.Errors); } } // 入参DTO,可放在Shared项目中前后端共用 public class UpdateProfileRequest { public string PhoneNumber { get; set; } // public string FirstName { get; set; } // public string LastName { get; set; } }
如果需要扩展AspNetUsers表的字段,自定义继承IdentityUser的子类,迁移数据库即可。
Blazor WASM前端页面实现
默认个人账户模板生成的WASM项目,HttpClient已经自动附带当前用户的JWT令牌,无需手动处理认证头。
新建Pages/EditProfile.razor页面:
@page "/edit-profile" @attribute [Authorize] @inject HttpClient Http @inject NavigationManager NavManager <pagetitle>编辑个人信息</pagetitle> <h3>个人信息编辑</h3> @if (userProfile == null) { <p>加载中...</p> } else { <div class="col-md-6"> <EditForm Model="@userProfile" OnValidSubmit="@SaveProfile"> <DataAnnotationsValidator /> <ValidationSummary /> <div class="mb-3"> <label class="form-label">邮箱</label> <InputText class="form-control" @bind-Value="@userProfile.Email" disabled /> <small class="text-muted">邮箱为固定标识,不可直接修改</small> </div> <div class="mb-3"> <label class="form-label">手机号码</label> <InputText class="form-control" @bind-Value="@userProfile.PhoneNumber" /> </div> <!-- 自定义字段对应添加输入项即可 <div class="mb-3"> <label class="form-label">名</label> <InputText class="form-control" @bind-Value="@userProfile.FirstName" required /> </div> <div class="mb-3"> <label class="form-label">姓</label> <InputText class="form-control" @bind-Value="@userProfile.LastName" required /> </div> --> <button type="submit" class="btn btn-primary" disabled="@isSaving"> @(isSaving ? "保存中..." : "保存修改") </button> </EditForm> </div> } @code { private UserProfileDto userProfile; private bool isSaving; protected override async Task OnInitializedAsync() { userProfile = await Http.GetFromJsonAsync<UserProfileDto>("api/UserProfile"); } private async Task SaveProfile() { isSaving = true; var response = await Http.PutAsJsonAsync("api/UserProfile", userProfile); if (response.IsSuccessStatusCode) { NavManager.NavigateTo("/"); } isSaving = false; } public class UserProfileDto { public string Email { get; set; } public string PhoneNumber { get; set; } // public string FirstName { get; set; } // public string LastName { get; set; } } }
安全注意事项
- 核心权限校验逻辑必须全部在服务端实现,前端的
[Authorize]仅做UI层拦截,不能作为安全依赖 - 所有用户身份标识只从服务端Claims中获取,禁止接受前端传递的用户ID、邮箱等参数作为查询/更新条件
- 如涉及邮箱、密码等敏感信息修改,需额外添加二次验证逻辑(如原密码校验、短信验证码校验)
内容的提问来源于stack exchange,提问作者Stephen Barr
相关产品推荐
相关产品推荐

