Individual authentication 模板
我們首先用VSCode新建一個mvc的網站,這個網站創立的時候回自動為我們創建Identuty Core以及EF Core的代碼示例,我們可以用命令 dotnet new mvc --help 來查看一些參數:
由於我們創建mvc項目是默認不帶Identity驗證的,所以我們要加上下面的 -au|--auth 參數來使用Individual創建帶Identity驗證的網站
還有一個參數 -uld|--use-local-db 參數來使用本地數據庫,在VSCode默認的是使用SqlLite,在VS2017中默認使用的是LocalDB。
接下來我們就可以使用以下命令創建包含Identity的mvc網站IdentitySample
dotnet new mvc -au Individual -uld --name IdentitySample
創建完成后我們打開創建的項目,然后查看appsettings.json,發現已經默認創建了數據庫連接,我們可以將數據庫修改成自己的數據庫地址
同時我們可以打開Startup.cs可以查看數據庫配置以及Identity驗證已經幫我們添加好了
接下來我們初始化一下數據庫,否則啟動之后會報錯,所以我們要使用EF Core的Migration命令來初始化數據庫。
我們使用的第一個命令是 dotnet ef database update 他會根據當前migration文件夾下的文件來幫我們進行數據庫的創建和更新。
我們可以在終端看到執行的sql語句

PS C:\Users\Administrator\Desktop\Demo2\IdentitySample> dotnet ef database update info: Microsoft.AspNetCore.DataProtection.KeyManagement.XmlKeyManager[0] User profile is available. Using 'C:\Users\Administrator\AppData\Local\ASP.NET\DataProtection-Keys' as key repository and Windows DPAPI to encrypt keys at rest. info: Microsoft.EntityFrameworkCore.Infrastructure[100403] Entity Framework Core 2.0.0-rtm-26452 initialized 'ApplicationDbContext' using provider 'Microsoft.EntityFrameworkCore.SqlServer' with options: None info: Microsoft.EntityFrameworkCore.Database.Command[200101] Executed DbCommand (714ms) [Parameters=[], CommandType='Text', CommandTimeout='60'] CREATE DATABASE [aspnet-IdentitySample-9A22BB3E-8D53-4F44-B533-2EF927C959DE]; info: Microsoft.EntityFrameworkCore.Database.Command[200101] Executed DbCommand (192ms) [Parameters=[], CommandType='Text', CommandTimeout='60'] IF SERVERPROPERTY('EngineEdition') <> 5 EXEC(N'ALTER DATABASE [aspnet-IdentitySample-9A22BB3E-8D53-4F44-B533-2EF927C959DE] SET READ_COMMITTED_SNAPSHOT ON;'); info: Microsoft.EntityFrameworkCore.Database.Command[200101] Executed DbCommand (7ms) [Parameters=[], CommandType='Text', CommandTimeout='30'] CREATE TABLE [__EFMigrationsHistory] ( [MigrationId] nvarchar(150) NOT NULL, [ProductVersion] nvarchar(32) NOT NULL, CONSTRAINT [PK___EFMigrationsHistory] PRIMARY KEY ([MigrationId]) ); info: Microsoft.EntityFrameworkCore.Database.Command[200101] Executed DbCommand (33ms) [Parameters=[], CommandType='Text', CommandTimeout='30'] SELECT OBJECT_ID(N'__EFMigrationsHistory'); info: Microsoft.EntityFrameworkCore.Database.Command[200101] Executed DbCommand (1ms) [Parameters=[], CommandType='Text', CommandTimeout='30'] SELECT [MigrationId], [ProductVersion] FROM [__EFMigrationsHistory] ORDER BY [MigrationId]; info: Microsoft.EntityFrameworkCore.Migrations[200402] Applying migration '00000000000000_CreateIdentitySchema'. Applying migration '00000000000000_CreateIdentitySchema'. info: Microsoft.EntityFrameworkCore.Database.Command[200101] Executed DbCommand (1ms) [Parameters=[], CommandType='Text', CommandTimeout='30'] CREATE TABLE [AspNetRoles] ( [Id] nvarchar(450) NOT NULL, [ConcurrencyStamp] nvarchar(max) NULL, [Name] nvarchar(256) NULL, [NormalizedName] nvarchar(256) NULL, CONSTRAINT [PK_AspNetRoles] PRIMARY KEY ([Id]) ); info: Microsoft.EntityFrameworkCore.Database.Command[200101] Executed DbCommand (15ms) [Parameters=[], CommandType='Text', CommandTimeout='30'] CREATE TABLE [AspNetUserTokens] ( [UserId] nvarchar(450) NOT NULL, [LoginProvider] nvarchar(450) NOT NULL, [Name] nvarchar(450) NOT NULL, [Value] nvarchar(max) NULL, CONSTRAINT [PK_AspNetUserTokens] PRIMARY KEY ([UserId], [LoginProvider], [Name]) ); info: Microsoft.EntityFrameworkCore.Database.Command[200101] Executed DbCommand (15ms) [Parameters=[], CommandType='Text', CommandTimeout='30'] CREATE TABLE [AspNetUsers] ( [Id] nvarchar(450) NOT NULL, [AccessFailedCount] int NOT NULL, [ConcurrencyStamp] nvarchar(max) NULL, [Email] nvarchar(256) NULL, [EmailConfirmed] bit NOT NULL, [LockoutEnabled] bit NOT NULL, [LockoutEnd] datetimeoffset NULL, [NormalizedEmail] nvarchar(256) NULL, [NormalizedUserName] nvarchar(256) NULL, [PasswordHash] nvarchar(max) NULL, [PhoneNumber] nvarchar(max) NULL, [PhoneNumberConfirmed] bit NOT NULL, [SecurityStamp] nvarchar(max) NULL, [TwoFactorEnabled] bit NOT NULL, [UserName] nvarchar(256) NULL, CONSTRAINT [PK_AspNetUsers] PRIMARY KEY ([Id]) ); info: Microsoft.EntityFrameworkCore.Database.Command[200101] Executed DbCommand (8ms) [Parameters=[], CommandType='Text', CommandTimeout='30'] CREATE TABLE [AspNetRoleClaims] ( [Id] int NOT NULL IDENTITY, [ClaimType] nvarchar(max) NULL, [ClaimValue] nvarchar(max) NULL, [RoleId] nvarchar(450) NOT NULL, CONSTRAINT [PK_AspNetRoleClaims] PRIMARY KEY ([Id]), CONSTRAINT [FK_AspNetRoleClaims_AspNetRoles_RoleId] FOREIGN KEY ([RoleId]) REFERENCES [AspNetRoles] ([Id]) ON DELETE CASCADE ); info: Microsoft.EntityFrameworkCore.Database.Command[200101] Executed DbCommand (1ms) [Parameters=[], CommandType='Text', CommandTimeout='30'] CREATE TABLE [AspNetUserClaims] ( [Id] int NOT NULL IDENTITY, [ClaimType] nvarchar(max) NULL, [ClaimValue] nvarchar(max) NULL, [UserId] nvarchar(450) NOT NULL, CONSTRAINT [PK_AspNetUserClaims] PRIMARY KEY ([Id]), CONSTRAINT [FK_AspNetUserClaims_AspNetUsers_UserId] FOREIGN KEY ([UserId]) REFERENCES [AspNetUsers] ([Id]) ON DELETE CASCADE ); info: Microsoft.EntityFrameworkCore.Database.Command[200101] Executed DbCommand (1ms) [Parameters=[], CommandType='Text', CommandTimeout='30'] CREATE TABLE [AspNetUserLogins] ( [LoginProvider] nvarchar(450) NOT NULL, [ProviderKey] nvarchar(450) NOT NULL, [ProviderDisplayName] nvarchar(max) NULL, [UserId] nvarchar(450) NOT NULL, CONSTRAINT [PK_AspNetUserLogins] PRIMARY KEY ([LoginProvider], [ProviderKey]), CONSTRAINT [FK_AspNetUserLogins_AspNetUsers_UserId] FOREIGN KEY ([UserId]) REFERENCES [AspNetUsers] ([Id]) ON DELETE CASCADE ); info: Microsoft.EntityFrameworkCore.Database.Command[200101] Executed DbCommand (2ms) [Parameters=[], CommandType='Text', CommandTimeout='30'] CREATE TABLE [AspNetUserRoles] ( [UserId] nvarchar(450) NOT NULL, [RoleId] nvarchar(450) NOT NULL, CONSTRAINT [PK_AspNetUserRoles] PRIMARY KEY ([UserId], [RoleId]), CONSTRAINT [FK_AspNetUserRoles_AspNetRoles_RoleId] FOREIGN KEY ([RoleId]) REFERENCES [AspNetRoles] ([Id]) ON DELETE CASCADE, CONSTRAINT [FK_AspNetUserRoles_AspNetUsers_UserId] FOREIGN KEY ([UserId]) REFERENCES [AspNetUsers] ([Id]) ON DELETE CASCADE ); info: Microsoft.EntityFrameworkCore.Database.Command[200101] Executed DbCommand (0ms) [Parameters=[], CommandType='Text', CommandTimeout='30'] CREATE INDEX [RoleNameIndex] ON [AspNetRoles] ([NormalizedName]); info: Microsoft.EntityFrameworkCore.Database.Command[200101] Executed DbCommand (0ms) [Parameters=[], CommandType='Text', CommandTimeout='30'] CREATE INDEX [IX_AspNetRoleClaims_RoleId] ON [AspNetRoleClaims] ([RoleId]); info: Microsoft.EntityFrameworkCore.Database.Command[200101] Executed DbCommand (0ms) [Parameters=[], CommandType='Text', CommandTimeout='30'] CREATE INDEX [IX_AspNetUserClaims_UserId] ON [AspNetUserClaims] ([UserId]); info: Microsoft.EntityFrameworkCore.Database.Command[200101] Executed DbCommand (0ms) [Parameters=[], CommandType='Text', CommandTimeout='30'] CREATE INDEX [IX_AspNetUserLogins_UserId] ON [AspNetUserLogins] ([UserId]); info: Microsoft.EntityFrameworkCore.Database.Command[200101] Executed DbCommand (0ms) [Parameters=[], CommandType='Text', CommandTimeout='30'] CREATE INDEX [IX_AspNetUserRoles_RoleId] ON [AspNetUserRoles] ([RoleId]); info: Microsoft.EntityFrameworkCore.Database.Command[200101] Executed DbCommand (0ms) [Parameters=[], CommandType='Text', CommandTimeout='30'] CREATE INDEX [IX_AspNetUserRoles_UserId] ON [AspNetUserRoles] ([UserId]); info: Microsoft.EntityFrameworkCore.Database.Command[200101] Executed DbCommand (0ms) [Parameters=[], CommandType='Text', CommandTimeout='30'] CREATE INDEX [EmailIndex] ON [AspNetUsers] ([NormalizedEmail]); info: Microsoft.EntityFrameworkCore.Database.Command[200101] Executed DbCommand (0ms) [Parameters=[], CommandType='Text', CommandTimeout='30'] CREATE UNIQUE INDEX [UserNameIndex] ON [AspNetUsers] ([NormalizedUserName]); info: Microsoft.EntityFrameworkCore.Database.Command[200101] Executed DbCommand (1ms) [Parameters=[], CommandType='Text', CommandTimeout='30'] INSERT INTO [__EFMigrationsHistory] ([MigrationId], [ProductVersion]) VALUES (N'00000000000000_CreateIdentitySchema', N'2.0.0-rtm-26452'); Done.
然后我們去數據庫就可以查看到我們創建的數據庫和數據表了
接下來我們運行 dotnet run 來運行我們創建的mvc網站,發現已經實現了登錄和注冊,以及前后台驗證
EF Core Migration
手動命令行的方式
VSCode | VS2017 | 說明 |
dotnet ef migrations add InitialCreate | Add-Migration | 對當前EF實體模型增加一個配置文件 |
dotnet ef database update | Update-Database | 對當前版本進行更新 |
dotnet ef migrations remove | Remove-Migration | 刪除最新的Migration |
dotnet ef database update LastGoodMigration | Update-Database LastGoodMigration | 對指定版本進行更新 |
dotnet ef migrations script | Script-Migration | 對當前更新生成一個sql的腳本,我們可以使用腳本到數據庫取執行 |
接下來我們實踐一下,我們來操作一下數據庫中的AspNetUsers表,我們打開項目中的ApplicationUser.cs,添加新屬性NewColumn
然后我們使用命令 dotnet ef migrations add AddNewColumn 生成配置文件
這個時候數據庫是沒有進行更新的,我們只有執行 dotnet ef database update 命令才會更新到數據庫
接下來我們繼續打開項目中的ApplicationUser.cs,添加新屬性Address
然后我們使用命令 dotnet ef migrations add AddAddress 生成配置文件
執行 dotnet ef database update 命令更新到數據庫
接下來我們使用 dotnet ef database update AddNewColumn 就可以將數據庫回滾到指定的版本
接下來執行 dotnet ef migrations remove 命令會將當前項目之后沒有用的配置文件刪除,我們這里執行后會將AddAddress配置文件刪除

PS C:\Users\Administrator\Desktop\Demo2\IdentitySample> dotnet ef migrations remove info: Microsoft.AspNetCore.DataProtection.KeyManagement.XmlKeyManager[0] User profile is available. Using 'C:\Users\Administrator\AppData\Local\ASP.NET\DataProtection-Keys' as key repository and Windows DPAPI to encrypt keys at rest. info: Microsoft.EntityFrameworkCore.Infrastructure[100403] Entity Framework Core 2.0.0-rtm-26452 initialized 'ApplicationDbContext' using provider 'Microsoft.EntityFrameworkCore.SqlServer' with options: None info: Microsoft.EntityFrameworkCore.Database.Command[200101] Executed DbCommand (8ms) [Parameters=[], CommandType='Text', CommandTimeout='30'] SELECT OBJECT_ID(N'__EFMigrationsHistory'); info: Microsoft.EntityFrameworkCore.Database.Command[200101] Executed DbCommand (8ms) [Parameters=[], CommandType='Text', CommandTimeout='30'] SELECT [MigrationId], [ProductVersion] FROM [__EFMigrationsHistory] ORDER BY [MigrationId]; Removing migration '20180105053249_AddAddress'. Reverting model snapshot. Done.
我們可以用 dotnet ef migrations script 命令來生成sql腳本,我們可以將sql拷貝出來放在數據庫取執行。

IF OBJECT_ID(N'__EFMigrationsHistory') IS NULL BEGIN CREATE TABLE [__EFMigrationsHistory] ( [MigrationId] nvarchar(150) NOT NULL, [ProductVersion] nvarchar(32) NOT NULL, CONSTRAINT [PK___EFMigrationsHistory] PRIMARY KEY ([MigrationId]) ); END; GO CREATE TABLE [AspNetRoles] ( [Id] nvarchar(450) NOT NULL, [ConcurrencyStamp] nvarchar(max) NULL, [Name] nvarchar(256) NULL, [NormalizedName] nvarchar(256) NULL, CONSTRAINT [PK_AspNetRoles] PRIMARY KEY ([Id]) ); GO CREATE TABLE [AspNetUserTokens] ( [UserId] nvarchar(450) NOT NULL, [LoginProvider] nvarchar(450) NOT NULL, [Name] nvarchar(450) NOT NULL, [Value] nvarchar(max) NULL, CONSTRAINT [PK_AspNetUserTokens] PRIMARY KEY ([UserId], [LoginProvider], [Name]) ); GO CREATE TABLE [AspNetUsers] ( [Id] nvarchar(450) NOT NULL, [AccessFailedCount] int NOT NULL, [ConcurrencyStamp] nvarchar(max) NULL, [Email] nvarchar(256) NULL, [EmailConfirmed] bit NOT NULL, [LockoutEnabled] bit NOT NULL, [LockoutEnd] datetimeoffset NULL, [NormalizedEmail] nvarchar(256) NULL, [NormalizedUserName] nvarchar(256) NULL, [PasswordHash] nvarchar(max) NULL, [PhoneNumber] nvarchar(max) NULL, [PhoneNumberConfirmed] bit NOT NULL, [SecurityStamp] nvarchar(max) NULL, [TwoFactorEnabled] bit NOT NULL, [UserName] nvarchar(256) NULL, CONSTRAINT [PK_AspNetUsers] PRIMARY KEY ([Id]) ); GO CREATE TABLE [AspNetRoleClaims] ( [Id] int NOT NULL IDENTITY, [ClaimType] nvarchar(max) NULL, [ClaimValue] nvarchar(max) NULL, [RoleId] nvarchar(450) NOT NULL, CONSTRAINT [PK_AspNetRoleClaims] PRIMARY KEY ([Id]), CONSTRAINT [FK_AspNetRoleClaims_AspNetRoles_RoleId] FOREIGN KEY ([RoleId]) REFERENCES [AspNetRoles] ([Id]) ON DELETE CASCADE ); GO CREATE TABLE [AspNetUserClaims] ( [Id] int NOT NULL IDENTITY, [ClaimType] nvarchar(max) NULL, [ClaimValue] nvarchar(max) NULL, [UserId] nvarchar(450) NOT NULL, CONSTRAINT [PK_AspNetUserClaims] PRIMARY KEY ([Id]), CONSTRAINT [FK_AspNetUserClaims_AspNetUsers_UserId] FOREIGN KEY ([UserId]) REFERENCES [AspNetUsers] ([Id]) ON DELETE CASCADE ); GO CREATE TABLE [AspNetUserLogins] ( [LoginProvider] nvarchar(450) NOT NULL, [ProviderKey] nvarchar(450) NOT NULL, [ProviderDisplayName] nvarchar(max) NULL, [UserId] nvarchar(450) NOT NULL, CONSTRAINT [PK_AspNetUserLogins] PRIMARY KEY ([LoginProvider], [ProviderKey]), CONSTRAINT [FK_AspNetUserLogins_AspNetUsers_UserId] FOREIGN KEY ([UserId]) REFERENCES [AspNetUsers] ([Id]) ON DELETE CASCADE ); GO CREATE TABLE [AspNetUserRoles] ( [UserId] nvarchar(450) NOT NULL, [RoleId] nvarchar(450) NOT NULL, CONSTRAINT [PK_AspNetUserRoles] PRIMARY KEY ([UserId], [RoleId]), CONSTRAINT [FK_AspNetUserRoles_AspNetRoles_RoleId] FOREIGN KEY ([RoleId]) REFERENCES [AspNetRoles] ([Id]) ON DELETE CASCADE, CONSTRAINT [FK_AspNetUserRoles_AspNetUsers_UserId] FOREIGN KEY ([UserId]) REFERENCES [AspNetUsers] ([Id]) ON DELETE CASCADE ); GO CREATE INDEX [RoleNameIndex] ON [AspNetRoles] ([NormalizedName]); GO CREATE INDEX [IX_AspNetRoleClaims_RoleId] ON [AspNetRoleClaims] ([RoleId]); GO CREATE INDEX [IX_AspNetUserClaims_UserId] ON [AspNetUserClaims] ([UserId]); GO CREATE INDEX [IX_AspNetUserLogins_UserId] ON [AspNetUserLogins] ([UserId]); GO CREATE INDEX [IX_AspNetUserRoles_RoleId] ON [AspNetUserRoles] ([RoleId]); GO CREATE INDEX [IX_AspNetUserRoles_UserId] ON [AspNetUserRoles] ([UserId]); GO CREATE INDEX [EmailIndex] ON [AspNetUsers] ([NormalizedEmail]); GO CREATE UNIQUE INDEX [UserNameIndex] ON [AspNetUsers] ([NormalizedUserName]); GO INSERT INTO [__EFMigrationsHistory] ([MigrationId], [ProductVersion]) VALUES (N'00000000000000_CreateIdentitySchema', N'2.0.0-rtm-26452'); GO DROP INDEX [UserNameIndex] ON [AspNetUsers]; GO DROP INDEX [IX_AspNetUserRoles_UserId] ON [AspNetUserRoles]; GO DROP INDEX [RoleNameIndex] ON [AspNetRoles]; GO ALTER TABLE [AspNetUsers] ADD [NewColumn] nvarchar(max) NULL; GO CREATE UNIQUE INDEX [UserNameIndex] ON [AspNetUsers] ([NormalizedUserName]) WHERE [NormalizedUserName] IS NOT NULL; GO CREATE UNIQUE INDEX [RoleNameIndex] ON [AspNetRoles] ([NormalizedName]) WHERE [NormalizedName] IS NOT NULL; GO ALTER TABLE [AspNetUserTokens] ADD CONSTRAINT [FK_AspNetUserTokens_AspNetUsers_UserId] FOREIGN KEY ([UserId]) REFERENCES [AspNetUsers] ([Id]) ON DELETE CASCADE; GO INSERT INTO [__EFMigrationsHistory] ([MigrationId], [ProductVersion]) VALUES (N'20180105034732_AddNewColumn', N'2.0.0-rtm-26452'); GO