在VS2022的ASP.NET Core Angular模板中显示用户姓名而非邮箱
解决方案:在Angular客户端显示自定义用户字段(FirstName/LastName)
要解决前端显示邮箱而非自定义姓名的问题,需要从后端配置Identity Server返回自定义字段和前端修改获取/显示逻辑两部分入手:
后端配置:让Identity Server返回自定义用户字段
默认情况下,Identity Server不会自动将ApplicationUser的自定义字段(FirstName/LastName)加入到用户的Claims集合中,需要手动配置:
方法1:实现自定义ProfileService
创建一个CustomProfileService类,实现IProfileService接口,动态将用户的自定义字段映射为标准Claims:
using Microsoft.AspNetCore.Identity; using Microsoft.IdentityModel.Tokens; using System.Security.Claims; public class CustomProfileService : IProfileService { private readonly UserManager<ApplicationUser> _userManager; public CustomProfileService(UserManager<ApplicationUser> userManager) { _userManager = userManager; } public async Task GetProfileDataAsync(ProfileDataRequestContext context) { var user = await _userManager.GetUserAsync(context.Subject); if (user == null) return; var claims = new List<Claim> { new Claim(ClaimTypes.GivenName, user.FirstName ?? string.Empty), new Claim(ClaimTypes.Surname, user.LastName ?? string.Empty) }; context.IssuedClaims.AddRange(claims); } public async Task IsActiveAsync(IsActiveContext context) { var user = await _userManager.GetUserAsync(context.Subject); context.IsActive = user != null; } }
在Program.cs中注册这个服务:
builder.Services.AddScoped<IProfileService, CustomProfileService>();
方法2:在用户注册时直接添加Claims
如果不需要动态获取用户信息,也可以在用户注册阶段直接将自定义字段添加为Claims:
// 注册逻辑示例 var user = new ApplicationUser { UserName = model.Email, Email = model.Email, FirstName = model.FirstName, LastName = model.LastName }; var result = await _userManager.CreateAsync(user, model.Password); if (result.Succeeded) { await _userManager.AddClaimsAsync(user, new[] { new Claim(ClaimTypes.GivenName, user.FirstName), new Claim(ClaimTypes.Surname, user.LastName) }); }
前端修改:获取并显示自定义姓名
1. 调整login-menu组件的用户数据获取逻辑
更新login-menu.component.ts中的ngOnInit方法,从用户profile中提取given_name(对应FirstName)和family_name(对应LastName)并拼接:
ngOnInit() { this.isAuthenticated = this.authorizeService.isAuthenticated(); this.userName = this.authorizeService.getUser().pipe(map(u => { if (!u) return ''; // 拼接名和姓,兼容不同的Claim命名方式 return `${u.given_name || u.firstName} ${u.family_name || u.lastName}`.trim(); })); }
2. 更新前端模板显示
修改login-menu.html,将原来显示邮箱的部分替换为拼接后的姓名:
<!-- 替换原有的用户名显示逻辑 --> <span *ngIf="(userName | async) as fullName">{{ fullName }}</span>
(可选)处理Profile字段映射
如果前端user.profile中没有自动映射given_name/family_name,可以在authorize.service.ts的completeSignIn方法中手动提取Claims:
public async completeSignIn(url: string): Promise<IAuthenticationResult> { try { await this.ensureUserManagerInitialized(); const user = await this.userManager!.signinCallback(url); // 手动提取自定义Claims,兼容标准Claim类型 const extendedProfile = { ...user.profile, given_name: user.profile.given_name || user.profile['http://schemas.xmlsoap.org/ws/2005/05/identity/claims/givenname'], family_name: user.profile.family_name || user.profile['http://schemas.xmlsoap.org/ws/2005/05/identity/claims/surname'] }; this.userSubject.next(extendedProfile); return this.success(user && user.state); } catch (error) { console.log('There was an error signing in: ', error); return this.error('There was an error signing in.'); } }
内容的提问来源于stack exchange,提问作者Alberto Espinoza
相关产品推荐
相关产品推荐

