【从0开始.NET CORE认证】-2 使用.Net Core Identity和EF Core

回顾

朋友们,距离上次从0开始.NET CORE认证-1发布已经过去一周了,上次第一篇文章,其实并没有涉及到Net Core Identity,就是简单的搭了一个项目,让大家对Identity中各种术语有个理解,明白他们出现的位置,已经他们出现能够达到某种功能。以及出现的位置顺序不同,则会出现什么不同的情况。

回顾一下上次写的主要的知识点

  1. Authentication和Authorization 是什么,怎么解释他们
  2. Claim和ClaimType又是什么,能举例子说明吗?
  3. ClaimsIdentity和ClaimsPrincipal的含义是什么,他们的从属关系是什么样的?
  4. app.UseAuthorization()和app.UseAuthentication()的意义是什么,能不能调换?

如果你对上面的问题都能回答,我相信你已经看懂了第一篇我讲了什么。

介绍

本章,我将会正式引入.Net Core Identity,然后还会引入EF Core,将.Net Core Identity的用户数据通过EF Core持久化到数据库中,用大白话就是把用户数据保存到数据库,以下思维导图的部分就是我们要做的部分

本文含有大量GIF图,请耐心等待加载


创建项目

我们继续使用第一篇文章中的解决方案,然后右键——添加——新建项目,选择ASP.NET CORE Web 应用程序,项目名称我们取为:AspNetCoreIdentityExample

同样,我们需要MVC框架来帮助我们搭建前端页面,所以修改一下StartUp.cs的内容,可以直接从上个项目BasiclyIdentity中复制一个基本代码,使其修改成这样。

 1 public class Startup
 2     {
 3         public void ConfigureServices(IServiceCollection services)
 4         {
 5             services.AddControllersWithViews();
 6         }
 7
 8         public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
 9         {
10             if (env.IsDevelopment())
11             {
12                 app.UseDeveloperExceptionPage();
13             }
14
15             app.UseRouting();
16
17             app.UseEndpoints(endpoints =>
18             {
19                 endpoints.MapDefaultControllerRoute();
20             });
21         }
22     }

StartUp.cs

具体操作看下面的图

然后我们创建一个控制器名为HomeController,里面定义两个Action,一个为Index,另外一个为Secert。也创建两个视图。我们可以直接复制BasiclyIdentity的视图和控制器,并且运行。查看能否正常运行。

具体操作请看图(

tips:一个解决方案内有多个可启动项目,注意调试的时候选择正确的项目):

调试,发现可以成功运行了。那我们可以开展下一步了

配置框架

我们将会使用.Net Core Identity和EF Core帮助我们管理用户,他并不会默认自带在我们创建的项目中

所以我们需要引入五个Nuget包:

  1. Microsoft.AspNetCore.Identity
  2. Microsoft.AspNetCore.Identity.EntityFrameworkCore
  3. Microsoft.EntityFrameworkCore
  4. Microsoft.EntityFrameworkCore.SqlServer
  5. Microsoft.EntityFrameworkCore.Tools

这五个包负责不同的功能,

  1. Microsoft.AspNetCore.Identity //包含AspNetCore.Identity的框架,我们可以使用里面认证授权等功能,最基础的功能
  2. Microsoft.AspNetCore.Identity.EntityFrameworkCore //对AspNetCore.Identity的扩展,让其可以和EF Core配合使用
  3. Microsoft.EntityFrameworkCore //EF Core 这个不用我多说了吧
  4. Microsoft.EntityFrameworkCore.SqlServer //EF Core用来连接sql server的包,如果使用mysql,最后一个换名字就行了
  5. Microsoft.EntityFrameworkCore.Tools //在VS 命令行里面迁移数据需要用的命令 add-migration  update-database

然后安装好这五个包之后,创建一个数据库(这个数据库可以是专门存放用户信息的数据库,也可以是跟业务耦合在一起的数据库)因为这个只是关于用户管理的示例项目,所以没有业务。所以我会创建一个AppUserDb的数据库,在项目中的appsetting.json中会配置好连接字符串

链接字符串的格式

Server=.;Database=TBS;User ID=AppUserDb;Password=Dd112233;Trusted_Connection=False;MultipleActiveResultSets=true

具体操作看图-安装NuGet包

创建数据库和配置连接字符串

配置EF Core

我们先开始在项目下面创建一个Data文件夹,然后创建数据库上下文AppDbContext.cs,让其继承DbContext,然后在StartUp.cs中注入这个上下文,随后执行迁移命令,通过EF Core在数据库内生成相应的表。

创建上下文,并注入。主要是以下代码

 1 using Microsoft.EntityFrameworkCore;
 2
 3 namespace AspNetCoreIdentityExample.Data
 4 {
 5     public class AppDbContext:DbContext
 6     {
 7         public AppDbContext(DbContextOptions<AppDbContext> options)
 8             :base(options)
 9         {
10
11         }
12     }
13 }

AppDbContext.cs

1  services.AddDbContext<AppDbContext>(config =>
2             {
3                 config.UseSqlServer(configuration.GetSection("ConnectionString").Value, opt =>
4                 {
5                     //opt.CommandTimeout(6000);
6                 });
7             });

在ConfigureServices增加下列代码

具体操作看图:

配置.Net Core Identity

我们在StartUp.cs文件中引用.Net Core Identity,其中IdentityUser和IdentityRole是框架内置的用户类和角色类,如果我们需要做扩展,只需要继承此类即可

主要是以下代码

1 services.AddIdentity<IdentityUser, IdentityRole>()
2                 .AddDefaultTokenProviders();

在ConfigureServices增加下列代码

你认为到此结束了吗?其实还没有,在第一篇文章中,我们使用了Cookie作为认证授权的条件,但是我们这里好像没有指定什么东西作为登录授权的条件。所以我们也要为.Net Core Identity开启Cookies认证(.Net Core Identity不仅仅支持Cookie,此话后文再说)

1 services.ConfigureApplicationCookie(config =>
2             {
3                 config.Cookie.Name = ".NetCoreIdentity.Cookies";
4                 config.LoginPath = "/Home/Login"; //让没有Cookie的用户访问被保护的接口时候跳转到这个Api
5             });

在ConfigureServices增加下列代码

具体操作看下图:

同理,我们既然指定了当用户没有授权的时候,要跳转到/Home/Login,所以我们要新增两个页面一个是登录页,一个是注册页

在HomeController里面增加两个Action,使其变成下面的代码,然后增加两个页面一个是Login.cshtml一个是Register.cshtml,代码如下

 1 using Microsoft.AspNetCore.Authentication;
 2 using Microsoft.AspNetCore.Authorization;
 3 using Microsoft.AspNetCore.Mvc;
 4 using System.Collections.Generic;
 5 using System.Security.Claims;
 6
 7 namespace AspNetCoreIdentityExample.Controllers
 8 {
 9     public class HomeController : Controller
10     {
11         public IActionResult Index()
12         {
13             return View("Index");
14         }
15
16         [Authorize]
17         public IActionResult Secert()
18         {
19             return View("Secert");
20         }
21
22         [HttpGet]
23         public IActionResult Login()
24         {
25             return View("Login");
26         }
27
28         [HttpGet]
29         public IActionResult Register()
30         {
31             return View("Register");
32         }
33     }
34 }

HomeController

1 <h1>登录页</h1>
2 <form method="post" formaction="/Home/Login">
3     <input name="username" type="text" value="" />
4     <input name="password" type="password" value="" />
5     <button>登录</button>
6 </form>
7 <a href="/Home/Register">没有账号去注册</a>

Login.cshtml

1 <h1>注册页</h1>
2 <form method="post" formaction="/Home/Register">
3     <input name="username" type="text" value="" />
4     <input name="password" type="password" value="" />
5     <button>注册</button>
6 </form>
7 <a href="/Home/Login">已有账号去登陆</a>

Register.cshtml

操作请看图

好了,现在我们想一想我们的准备工作还差什么,我们已经有了登录、注册页面,然后认证方式也选了Cookie,我们也配置了数据库。

所以,我们目前还少了将登录、注册的业务逻辑、将用户数据持久化到数据库的代码。还有一个最重要的就是调用UseAuthorization()和UseAuthentication()方法,如果你不用这个方法,当访问带有[Authorize]标签的控制器的时候,就会出错,所以我们在StartUp.cs内配置一下

将Identity和EF Core结合起来

还记得我们安装了一个Microsoft.AspNetCore.Identity.EntityFrameworkCore的包吗?微软给我们已经写好了一个关于Identity的数据库上下文,让我们直接继承这个上下文就可以在EF Core中使用Identity。

所以我们修改一下,打开AppDbContext.cs将本来继承DbContext的,更改成IdentityDbContext

然后我们执行以下数据库迁移(EF Core 一般都是写代码,然后把代码中的类通过tools迁移到数据库,就不需要手动设置数据库了)。

在程序包控制台执行以下命令

1 Add-Migration InitUserDb -c AppDbContext -o AppMigration/User

然后执行

1 update-database

这样数据库就迁移成功了。具体操作看图

现在数据库也生成了,我们还需要在StartUp.cs将两个关系绑定起来

上面两个是孤立的,我们要增加一个方法改成下图

在认证中开启EntityFramworkStores;

现在运行一下我们的项目,能够正常运行,然后访问被保护的资源的时候会提示跳转到登录页。

具体看图

CURD用户

准备工作

微软很贴心的为我们准备了两个类,一个是负责管理用户信息的,一个是负责用户登录、登出转换权限的

  1. UserManager<T>
  2. SignInManager<T>

从字面意思也能看出来,UserManager是管理用户的,SiginManager是处理用户登录登出的,我们要在HomeController注入它们,然后使用它们,<T>是指用户类型,如果你有个类继承了IdentityUser这个类,那么你应该传入你自定义的类,否则传IdentityUser即可

代码如下

1 private readonly UserManager<IdentityUser> _userManager;
2         private readonly SignInManager<IdentityUser> _signInManager;
3
4         public HomeController(UserManager<IdentityUser> userManager,SignInManager<IdentityUser> signInManager)
5         {
6             _userManager = userManager;
7             _signInManager = signInManager;
8         }

注入UserManager和SiginManager

操作示意图如下

登录处理

一个用户需要登录,我们最简单的登录需要知道用户的用户名和密码,so,我们在Home控制器下创建一个action叫做Login,指定参数username和password,如果登录成功就跳转到/Home/Secert页面

代码如下

 1 [HttpPost]
 2         public async Task<IActionResult> Login(string username, string password)
 3         {
 4             var user = await _userManager.FindByNameAsync(username).ConfigureAwait(false);
 5             if (user != null)
 6             {
 7                 var signResult = await _signInManager.PasswordSignInAsync(user, password, false, false).ConfigureAwait(false);
 8                 if (signResult.Succeeded)
 9                 {
10                     return View("Secert");
11                 }
12             }
13             return View("Index");
14         }

Login

操作示意图如下

注册处理

一个用户需要注册,我们可能需要很多信息,但是最重要的也就是账号和密码这是我们必须要收集的,我们在Home控制器下创建一个action叫做Register,指定参数username和password,如果注册成功,那么我们就默认其已经登录,然后就跳转到/Home/Secert页面

代码如下

 1 [HttpPost]
 2         public async Task<IActionResult> Register(string username, string password)
 3         {
 4             var user = new IdentityUser
 5             {
 6                 UserName = username,
 7                 Email = "[email protected]",
 8             };
 9             var createResult = await _userManager.CreateAsync(user, password);
10             if (createResult.Succeeded)
11             {
12                 var signResult = await _signInManager.PasswordSignInAsync(user, password, false, false);
13                 if (signResult.Succeeded)
14                 {
15                     return View("Index");
16                 }
17                 else
18                 {
19                     return View("Index");
20                 }
21             }
22             else
23                 return View("Register");
24         }

Register

操作示意图如下

修改用户

修改用户我们必须先拿到这个用户,然后去修改,所以肯定会传递过来一个要修改用户的主键,我们在Home控制器下创建一个action叫做Update,这里我就演示成通过用户名修改,

增加一个个人信息页面名称为Update.cshtml

代码如下

1 [Authorize]
2         [HttpGet]
3         public async Task<IActionResult> Update()
4         {
5             var user = await _userManager.GetUserAsync(HttpContext.User);
6             ViewBag.Curs = user;
7             return View("Update");
8         }

在HomeController增加一个Action

然后增加一个页面

1 <h1>修改个人信息</h1>
2 <form formaction="/Home/Update" method="post">
3     <input name="username" value="@ViewBag.Curs.UserName" />
4     <input name="email" value="@ViewBag.Curs.Email" />
5     <button>确认修改</button>
6 </form>

Update.cshtml

代码如下

 1 [Authorize]
 2         [HttpPost]
 3         public async Task<IActionResult> Update(string username,string email)
 4         {
 5             var user = await _userManager.FindByNameAsync(username);
 6             if (user != null)
 7             {
 8                 user.Email = email;
 9                 var result = await _userManager.UpdateAsync(user);
10                 if (result.Succeeded)
11                     return RedirectToAction("Update");
12                 else
13                     return Ok("失败");
14             }
15             else
16                 return Ok("user is not existed");
17         }

Update

操作示意图如下

删除用户

跟修改用户一样,肯定是拿到主键才能删除,所以我演示成username作为主键拿到用户

代码如下

1 [Authorize]
2         [HttpGet]
3         public async Task<IActionResult> RemoveUser()
4         {
5             var user = await _userManager.GetUserAsync(HttpContext.User);
6             ViewBag.Curs = user;
7             return View("Remove");
8         }

在HomeController增加一个Action

然后增加一个页面

1 <h1>删除信息</h1>
2 <form formaction="/Home/RemoveUser" method="post">
3     <input name="username" value="@ViewBag.Curs.UserName" />
4     <button>确认删除</button>
5 </form>

RemoveUser.cshtml

 1 [Authorize]
 2         [HttpPost]
 3         public async Task<IActionResult> RemoveUser(string username)
 4         {
 5             var user = await _userManager.FindByNameAsync(username);
 6             if (user != null)
 7             {
 8                 var result = await _userManager.DeleteAsync(user);
 9                 if(result.Succeeded)
10                     return RedirectToAction("Index");
11                 else
12                     return Ok("失败");
13             }
14             return Ok("user is not existed");
15         }

RemoveUser

操作示意图如下

至此所有工作都准备好,测试一下。

可以看到,非常成功。有了.Net Core Identity配合EF Core就不需要我们自己去写一套用户管理逻辑了。

总结

  1. 学习了怎么使用.Net Core Identity和EF Core绑定使用
  2. 学习了两个基本类UserManager和SiginManager
  3. 学习了增删改用户信息

问题

  1. 如果我删除用户的时候,我把我自己删除了,然后我还能继续访问需要授权的页面吗?
  2. 更新个人信息的时候,更新成功了,Cookies会变吗?
  3. 隐藏小BUG,在注册用户的时候,会提示一个错误,并且需要修改一处代码!你能找到它吗?

又写完一篇,决定上传项目

gitee地址:https://gitee.com/JiMoKongTingChunYuWan_admin/IdentityDemo

github地址:https://github.com/Mrlie/IdentityDemo.git

下周见

原文地址:https://www.cnblogs.com/lihuadeblog/p/12153351.html

时间: 2025-01-09 22:33:04

【从0开始.NET CORE认证】-2 使用.Net Core Identity和EF Core的相关文章

EntityFramework Core技术线路(EF7已经更名为EF Core,并于2016年6月底发布)

官方文档英文地址:https://github.com/aspnet/EntityFramework/wiki/Roadmap 历经延期和更名,新版本的实体框架终于要和大家见面了,虽然还有点害羞.请大家多体谅! 下面正式进入主题: Entity Framework Core (EF Core) 下面是EF Core 的计划和技术线路,注意,这些计划是可能发现变化的,因为很多事是很难预测的.即便如此,我们还是尽可能保持计划的公开和透明,以解大家对EF Core期望,以及做出相应的安排. Sched

[转]EntityFramework Core技术线路(EF7已经更名为EF Core,并于2016年6月底发布)

本文转自:http://www.cnblogs.com/VolcanoCloud/p/5572408.html 官方文档英文地址:https://github.com/aspnet/EntityFramework/wiki/Roadmap 历经延期和更名,新版本的实体框架终于要和大家见面了,虽然还有点害羞.请大家多体谅! 下面正式进入主题: Entity Framework Core (EF Core) 下面是EF Core 的计划和技术线路,注意,这些计划是可能发现变化的,因为很多事是很难预测

ASP.NET Core中使用GraphQL - 第六章 使用EF Core作为持久化仓储

ASP.NET Core中使用GraphQL ASP.NET Core中使用GraphQL - 第一章 Hello World ASP.NET Core中使用GraphQL - 第二章 中间件 ASP.NET Core中使用GraphQL - 第三章 依赖注入 ASP.NET Core中使用GraphQL - 第四章 GrahpiQL ASP.NET Core中使用GraphQL - 第五章 字段, 参数, 变量 本篇中我将演示如何配置持久化仓储,这里原文中是使用的Postgres, 这里我改用

ASP.NET Core 开发-Entity Framework (EF) Core 1.0 Database First

ASP.NET Core 开发-Entity Framework Core 1.0 Database First,ASP.NET Core 1.0 EF Core操作数据库. Entity Framework Core 1.0 也已经发布了,可以适用于 .NET Core 1.0 及ASP.NET Core 1.0 . EF Core RC2 时,使用的Code First: http://www.cnblogs.com/linezero/p/EntityFrameworkCore.html E

在ASP.NET Core中通过EF Core实现一个简单的全局过滤查询

前言 不知道大家是否和我有同样的问题: 一般在数据库的设计阶段,会制定一些默认的规则,其中有一条硬性规定就是一定不要对任何表中的数据执行delete硬删除操作,因为每条数据对我们来说都是有用的,并且是值得分析的. 所以我们一般会在每张表中加一个"是否删除IsDeleted"或者"是否有效IsValid"的字段,来标识这条数据的状态是否可用! 那么疑问来了,在写SQL或者Linq的时候我们到底是要加上这个条件还是忽略这个条件呢?答案当然是根据实际业务需求和情况来决定.

SQLite EF Core Database Provider

原文链接 This database provider allows Entity Framework Core to be used with SQLite. The provider is maintained as part of the Entity Framework Core project. Supported Database Engines SQLite (3.7 onwards) Supported Platforms .NET Framework (4.5.1 onward

EF Core 基础知识

数据库连接字符串 在 ASP.NET Core 添加配置片段: { "ConnectionStrings": { "BloggingDatabase": "Server=(localdb)\\mssqllocaldb;Database=EFGetStarted.ConsoleApp.NewDb;Trusted_Connection=True;" } } 然后,配置对应的DbContext: public void ConfigureService

EF Core中执行Sql语句查询操作之FromSql,ExecuteSqlCommand,SqlQuery

一.目前EF Core的版本为V2.1 相比较EF Core v1.0 目前已经增加了不少功能. EF Core除了常用的增删改模型操作,Sql语句在不少项目中是不能避免的. 在EF Core中上下文,可以返货DbConnection ,执行sql语句.这是最底层的操作方式,代码写起来还是挺多的. 初次之外 EF Core中还支持 FromSql,ExecuteSqlCommand 连个方法,用于更方便的执行Sql语句. 另外,目前版本的EF Core 不支持SqlQuery,但是我们可以自己扩

EF Core 快速上手——EF Core 入门

EF Core 快速上手--EF Core 介绍 本章导航 从本书你能学到什么 对EF6.x 程序员的一些话 EF Core 概述 1.3.1 ORM框架的缺点 第一个EF Core应用 ??本文是对<Entity framework in action>部分章节的翻译,某些场景也会附上笔者实践的Demo.尽管很认真的斟酌,但是水平有限,还请各位批评和斧正. ??Entity Framework Core, 或者 EF Core,是一个方便软件工程师访问数据库的库.有很多方法来构建这样的一个库