学习分享 丨作者 / 郑 子 铭 丨公众号 / DotNet NB / CloudNative NB
任务40:介绍
1.Individual authentication 模板
2.EF Core Migration
3.Identity MVC:UI
4.Identity MVC: EF + Identity实现
5.Identity MVC:注册逻辑实现
6.Identity MVC:登录逻辑实现
7.Identity MVC:ReturnUrl实现
8.Identity MVC:Model后端验证
9.Identity MVC:Model前端验证
10.Identity MVC:DbContextSeed初始化
任务41:Individual authentication 模板
dotnet new mvc --help
Options:
-au|--auth The type of authentication to use
None - No authentication
Individual - Individual authentication
IndividualB2C - Individual authentication with Azure AD B2C
SingleOrg - Organizational authentication for a single tenant
MultiOrg - Organizational authentication for multiple tenants
Windows - Windows authentication
Default: None
-uld|--use-local-db Whether to use LocalDB instead of SQLite. This option only applies if --auth Individual or --auth IndividualB2C is specified.
bool - Optional
Default: false / (*) true
chcp 65001
dotnet new mvc -au Individual -uld --name IdentitySample
dotnet restore
dotnet ef database update
dotnet run
dotnet run
& 'C:\Program Files\Microsoft SQL Server\130\Tools\Binn\SqlLocalDB.exe' info mssqllocaldb
dotnet ef migrations add InitialCreat
dotnet ef database update
dotnet ef migrations remove
dotnet ef database update LastGoodMigration
dotnet ef migrations scrept
using System;
using Microsoft.AspNetCore.Identity;
namespace IdentitySample.Models
{
public class ApplicationUser : IdentityUser
{
public string NewColumn{get;set;}
}
}
dotnet ef migrations add AddNewColumn
dotnet ef database update
public string Address{get;set;}
dotnet ef migrations add AddAddress
dotnet ef database update
dotnet ef database update AddNewColumn
dotnet ef migrations remove
dotnet ef migrations script
public IActionResult Register()
{
return View();
}
public IActionResult Login()
{
return View();
}
public IActionResult MakeLogin()
@{
ViewData["Title"] = "Register";
}
@using MvcCookieAuthSample.ViewModels;
@model RegisterViewModel;
<h2>@ViewData["Title"]</h2>
<h3>@ViewData["Message"]</h3>
<p>Use this area to provide additional information.</p>
<div class="row">
<div class="col-md-4">
<form id="registerForm" method="post" novalidate="novalidate">
<h4>Create a new account.</h4>
<hr>
<div class="form-group">
<label asp-for="Input_Email">Email</label>
<input asp-for="Input_Email" class="form-control" type="email">
</div>
<div class="form-group">
<label asp-for="Input_Password">Password</label>
<input asp-for="Input_Password" class="form-control" type="password">
</div>
<div class="form-group">
<label asp-for="Input_ConfirmPassword">Confirm password</label>
<input asp-for="Input_ConfirmPassword" class="form-control" type="password">
</div>
<button id="registerSubmit" type="submit" class="btn btn-primary">Register</button>
<input name="__RequestVerificationToken" type="hidden" value="CfDJ8HHmKd6uCEtOsAkKHNEfx50wHX7kOnWmAzVSUOOnXiiks-t4chi5eY9XThPYt70X-X6qtCV55TTEowbXbnCAW-91KSw1XVqXqBd48bMdGuVeGHFeZU61gw9jtNtAUDP7gCYnN9J_9d6o5w9sL12jw1E"></form>
</div>
<div class="col-md-6 col-md-offset-2">
<section>
<h4>Use another service to register.</h4>
<hr>
<div>
<p>
There are no external authentication services configured. See <a href="https://go.microsoft.com/fwlink/?LinkID=532715">this article</a>
for details on setting up this ASP.NET application to support logging in via external services.
</p>
</div>
</section>
</div>
</div>
namespace MvcCookieAuthSample.ViewModels
{
public class RegisterViewModel
{
public string Input_Email{get;set;}
public string Input_Password{get;set;}
public string Input_ConfirmPassword{get;set;}
}
}
using Microsoft.AspNetCore.Identity;
namespace MvcCookieAuthSample.Models
{
// 默认主键GUID,可通过泛型修改
public class ApplicationUser : IdentityUser<int>
{
}
}
using Microsoft.AspNetCore.Identity;
namespace MvcCookieAuthSample.Models
{
// 默认主键GUID,可通过泛型修改
public class ApplicationUserRole : IdentityRole<int>
{
}
}
using Microsoft.EntityFrameworkCore;
using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
using MvcCookieAuthSample.Models;
namespace MvcCookieAuthSample.Data
{
public class ApplicationDbContext : IdentityDbContext<ApplicationUser, ApplicationUserRole, int>
{
public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options) : base(options)
{
}
}
}
using System.ComponentModel.DataAnnotations;
namespace MvcCookieAuthSample.ViewModels
{
public class RegisterViewModel
{
[Required]
[DataType(DataType.EmailAddress)]
public string Input_Email{get;set;}
[Required]
[DataType(DataType.Password)]
public string Input_Password{get;set;}
[Required]
[DataType(DataType.Password)]
public string Input_ConfirmPassword{get;set;}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.ComponentModel.DataAnnotations;
namespace MvcCookieAuthSample.ViewModels
{
public class LoginViewModel
{
[Required]
[DataType(DataType.EmailAddress)]
public string Input_Email { get; set; }
[Required]
[DataType(DataType.Password)]
public string Input_Password { get; set; }
}
}
[HttpPost]
public async Task<IActionResult> Login(LoginViewModel loginViewModel, string returnUrl = null)
{
if (ModelState.IsValid)
{
ViewData["ReturnUrl"] = returnUrl;
var user = await _userManager.FindByEmailAsync(loginViewModel.Input_Email);
if (user == null)
{
}
await _signInManager.SignInAsync(user, new AuthenticationProperties { IsPersistent = true });
//return RedirectToAction("Index", "Home");
return RedirectToLocal(returnUrl);
}
return View();
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Identity;
using MvcCookieAuthSample.Models;
using Microsoft.Extensions.DependencyInjection;
namespace MvcCookieAuthSample.Data
{
public class ApplicationDbContextSeed
{
private UserManager<ApplicationUser> _userManager;
public async Task SeedSync(ApplicationDbContext context, IServiceProvider services)
{
if (!context.Users.Any())
{
_userManager = services.GetRequiredService<UserManager<ApplicationUser>>();
var defaultUser = new ApplicationUser
{
UserName = "Administrator",
Email = "mingsonzheng003@outlook.com",
NormalizedUserName = "admin"
};
var result = await _userManager.CreateAsync(defaultUser, "Password$123");
if (!result.Succeeded)
throw new Exception("初始默认用户失败");
}
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Hosting;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
namespace MvcCookieAuthSample.Data
{
public static class WebHostMigrationExtensions
{
public static IWebHost MigrateDbContext<TContext>(this IWebHost host, Action<TContext, IServiceProvider> sedder)
where TContext : DbContext
{
using (var scope = host.Services.CreateScope())
{
var services = scope.ServiceProvider;
var logger = services.GetRequiredService<ILogger<TContext>>();
var context = services.GetService<TContext>();
try
{
context.Database.Migrate();
sedder(context, services);
logger.LogInformation($"执行DBContext { typeof(TContext).Name } seed执行成功");
}
catch (Exception ex)
{
logger.LogInformation($"执行DBContext { typeof(TContext).Name } seed执行失败");
}
}
return host;
}
}
}
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;
using MvcCookieAuthSample.Data;
namespace MvcCookieAuthSample
{
public class Program
{
public static void Main(string[] args)
{
CreateWebHostBuilder(args).Build()
.MigrateDbContext<ApplicationDbContext>((context, services) =>
{
new ApplicationDbContextSeed().SeedSync(context, services)
.Wait();
})
.Run();
}
public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>();
}
}