You need to enable JavaScript to run this app. Blazor WASM中如何对当前已认证用户的账户信息执行CRUD操作?
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.15 05:45:04