加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > asp.Net > 正文

每个页面上的ASP.NET MVC自定义用户字段

发布时间:2020-12-16 06:33:54 所属栏目:asp.Net 来源:网络整理
导读:背景: 我正在构建越来越多的Web应用程序,其中设计人员/模板制作者决定添加“个人资料图片”和其他一些用户相关数据,当然只有在有人登录时才会这样做. 与大多数ASP.NET MVC开发人员一样,我使用viewmodels为剃刀布局提供我需要显示的信息,这些信息源自存储库
背景:
我正在构建越来越多的Web应用程序,其中设计人员/模板制作者决定添加“个人资料图片”和其他一些用户相关数据,当然只有在有人登录时才会这样做.

与大多数ASP.NET MVC开发人员一样,我使用viewmodels为剃刀布局提供我需要显示的信息,这些信息源自存储库等.

通过使用很容易显示用户名

HttpContext.Current.User.Identity.Name

如果我想在这些页面上显示保存在我的后备数据存储区中的信息,该怎么办? ApplicationUser类中的自定义字段,如业务单位名称或个人资料图片CDN网址.

(为简单起见,我们假设我使用包含我的ApplicationUsers的实体框架(SQL数据库)的Identity Framework)

你怎么解决这个问题:

>不调度viewmodel / controller树(例如构建一个BaseViewModel或BaseController填充/提供此信息?
>无需为每个页面请求往返数据包这些细节?
>如果用户未登录,则不查询数据库?
>当您无法使用SESSION数据时(因为我的应用程序通常在多个Azure实例上扩展 – read why this isn’t possible here-我对SQL缓存或Redis缓存不感兴趣.

我已经考虑过使用部署新的自己的viewmodel – 但是仍然会在每个页面加载时绕过SQL数据库.会话数据现在是安全的,但是当用azure放大时,这也不是一种方法.知道什么是我最好的选择吗?

TLDR;

我想在用户登录时在我的应用程序的每个页面上显示用户配置文件信息(ApplicationUser)(anon access = allowed).如何在不查询每个页面请求的数据库的情况下显示此信息?如果没有Session类,我该怎么做?如何在不构建基类的情况下执行此操作?

解决方法

Identity的最佳方法是使用声明来存储有关用户的自定义数据. Sam的答案与我在这里所说的非常接近.我会详细说明一下.

在ApplicationUser类上,您有GenerateUserIdentityAsync方法,该方法用于创建用户的ClaimsIdentity:

public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<ApplicationUser,string> manager)
{
    // Note the authenticationType must match the one defined in CookieAuthenticationOptions.AuthenticationType
    var userIdentity = await manager.CreateIdentityAsync(this,DefaultAuthenticationTypes.ApplicationCookie);

   // Add custom user claims here
   userIdentity.AddClaims(new[]
   {
       new Claim("MyApp:FirstName",this.FirstName),//presuming FirstName is part of ApplicationUser class
       new Claim("MyApp:LastName",this.LastName),});

   return userIdentity;
}

这会在用户身份上添加键值对,最终在身份验证cookie中进行序列化和加密 – 这一点很重要.

用户登录后,您可以通过HttpContext.Current.User.Identity使用此标识 – 该对象实际上是ClaimsIdentity,其中声明来自cookie.因此,无论您在登录时间提出索赔,都可以随时使用,而无需深入了解您的数据库.

为了从索赔中获取数据,我通常会在IPrincipal上执行扩展方法

public static String GetFirstName(this IPrincipal principal)
{
    var claimsPrincipal = principal as ClaimsPrincipal;
    if (claimsPrincipal == null)
    {
        throw new DomainException("User is not authenticated");
    }

    var personNameClaim = claimsPrincipal.Claims.FirstOrDefault(c => c.Type == "MyApp:FirstName");
    if (personNameClaim != null)
    {
        return personNameClaim.Value;
    }

    return String.Empty;
}

这样您就可以从Razor视图访问您的声明数据:User.GetFirstName()

此操作非常快,因为它不需要来自DI容器的任何对象解析,也不会查询您的数据库.

唯一的障碍是当存储中的值实际更新时,auth cookie中的声明中的值不会刷新,直到用户注销并登录.但是你可以通过IAuehtenticationManager.Signout()自行强制它,并立即用更新的声明值重新签名.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读