简体   繁体   English

如何在客户端获取用户角色?

[英]How to get user role on client side?

I'm working on Angular web application with ASP.NET Core back end.我正在使用 ASP.NET 核心后端开发 Angular web 应用程序。 Started with built in "ASP.NET Core application with Angular" template project for Individual User Accounts authentication.从用于个人用户帐户身份验证的内置“带有 Angular 的 ASP.NET Core 应用程序”模板项目开始。 My problem is to get authenticated user's role on client side (i want to handle guards and menus within the roles).我的问题是在客户端获得经过身份验证的用户角色(我想在角色中处理警卫和菜单)。

Now i have API endpoint which give back the user's role from back end.现在我有 API 端点,它从后端返回用户的角色。

This endpoint i call when i need to know about user's role.当我需要了解用户的角色时,我会调用此端点。 Eg menu handling in nav-menu.component.ts例如 nav-menu.component.ts 中的菜单处理

But i know this is not the best solution.但我知道这不是最好的解决方案。 Possible code duplication etc.可能的代码重复等。

There is any other solution?还有其他解决方案吗?

I tried an another solution but dont works good.我尝试了另一种解决方案,但效果不佳。 In authorize service when user profile (which is any) is built up during signing in i should append roles to profile.在登录期间建立用户配置文件(可以是任何)时授权服务,我应该对 append 角色进行配置。 在此处输入图像描述

thanks for any advice感谢您的建议

It would've been more helpful if you have posted code snippets instead of images.如果您发布了代码片段而不是图像,那将会更有帮助。

However, from what I see in your code you are subscribing inside of another subscription and that's a bad practice.但是,根据我在您的代码中看到的内容,您正在订阅另一个订阅,这是一种不好的做法。

Here is how you should be doing this:以下是您应该如何执行此操作:

this.authorizeService
      .getUser()
      .pipe(
        // switchMap completes the previous observable and subscribe to the next one
        // the argument (user) is the data you get from the previous observable
        switchMap(user => (user ? this.authorizeService.getUserRoles(user.name) : of(null))))
      .subscribe(roles => this.roles = roles);

if you have authority to backend code it will be better to joint 2 endpoint into one,... eg.如果您有权使用后端代码,最好将 2 个端点合二为一,... 例如。 you can combine role endpoint in username endpoint and its give response in json like this您可以像这样在用户名端点中结合角色端点及其在 json 中的响应

{
  username:'femix',
  role:'admin'
}

it will save you 1 request instead of using 2 request just to get username and role.它将为您节省 1 个请求,而不是仅使用 2 个请求来获取用户名和角色。

After almost a year, I would like to update my question with answer.将近一年后,我想用答案更新我的问题。

I needed to create a ProfileService which implements IProfileService interface我需要创建一个实现IProfileService接口的ProfileService

public class ProfileService : IProfileService
{
    protected UserManager<ApplicationUser> UserManager;
    public ProfileService(UserManager<ApplicationUser> userManager)
    {
        UserManager = userManager;
    }

    public async Task GetProfileDataAsync(ProfileDataRequestContext context)
    {
        ApplicationUser user = await UserManager.GetUserAsync(context.Subject);

        IList<string> roles = await UserManager.GetRolesAsync(user);

        var claims = new List<Claim> {
            // here you can include other properties such as id, email, address, etc. as part of the jwt claim types
            new Claim(JwtClaimTypes.Email, user.Email),
            new Claim(JwtClaimTypes.Name, $"{user.Firstname} {user.Lastname}")
        };
        foreach (string role in roles)
        {
            // include the roles
            claims.Add(new Claim(JwtClaimTypes.Role, role));
        }

        context.IssuedClaims.AddRange(claims);
    }

    public Task IsActiveAsync(IsActiveContext context)
    {
        return Task.CompletedTask;
    }
}

Added DI registration to Startup向 Startup 添加了 DI 注册

services.AddTransient<IProfileService, ProfileService>();

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM