菜鳥入門【ASP.NET Core】14:MVC開發:UI、 EF + Identity實現、註冊實現、登錄實現

前言

以前咱們進行了MVC的web頁面的Cookie-based認證明現,接下來的開發咱們要基於以前的MvcCookieAuthSample項目作修改。css

MvcCookieAuthSample項目地址:http://www.cnblogs.com/wyt007/p/8128186.htmlhtml

UI

咱們首先在AccountController中添加兩個Actionjquery

複製代碼
        public IActionResult Register()        
     {
  
        return View();
 } public IActionResult Login() { return View(); }
複製代碼

而後在Views文件夾下新增Account文件夾並新增Register.cshtml與Login.cshtml視圖,樣式咱們儘可能從上一節的Identity視圖中拷貝過來。web

咱們還須要新建一個ViewModels,在ViewModels中新建RegisterViewModel.cs來接收表單提交的值以及來進行強類型視圖ajax

複製代碼
namespace MvcCookieAuthSample.ViewModels
{
    public class RegisterViewModel
    {
        //郵箱
        public string Email { get; set; }
        //密碼
        public string Password { get; set; }
        //確認密碼
        public string ConfirmedPassword { get; set; }
    }
}
複製代碼

Register.cshtml代碼(只保留部分拷貝過來的內容,並加入強類型視圖引用):sql

@{
ViewData["Title"] = "Register";
}shell

@using MvcCookieAuthSample.ViewModels;
@model RegisterViewModel;數據庫

<h2>@ViewData["Title"]</h2>
<h3>@ViewData["Message"]</h3>json

<div class="row">
<div class="col-md-4">
<form method="post">
<h4>Create a new account.</h4>
<hr />
<div class="form-group">
<label asp-for="Email"></label>
<input asp-for="Email" class="form-control" />
</div>
<div class="form-group">
<label asp-for="Password"></label>
<input asp-for="Password" class="form-control" />
</div>
<div class="form-group">
<label asp-for="ConfirmedPassword"></label>
<input asp-for="ConfirmedPassword" class="form-control" />
</div>
<button type="submit" class="btn btn-default">Register</button>
</form>
</div>
</div>bootstrap

 

Login.cshtml代碼(只保留部分拷貝過來的內容,並加入強類型視圖引用):

@{
ViewData["Title"] = "Login";
}

@using MvcCookieAuthSample.ViewModels;
@model RegisterViewModel;

<div class="row">
<div class="col-md-4">
<section>
<form method="post">
<h4>Use a local account to log in.</h4>
<hr />

<div class="form-group">
<label asp-for="Email"></label>
<input asp-for="Email" class="form-control" />
</div>

<div class="form-group">
<label asp-for="Password"></label>
<input asp-for="Password" type="password" class="form-control" />
</div>

<div class="form-group">
<button type="submit" class="btn btn-default">Log in</button>
</div>

</form>
</section>
</div>
</div>

 

而後在_Layout.cshtml中添加導航代碼:

<ul class="nav navbar-nav navbar-right">
    <li><a asp-area="" asp-controller="Account" asp-action="Register">Register</a></li>
    <li><a asp-area="" asp-controller="Account" asp-action="Login">Log in</a></li>
</ul>

而後運行網站,UI已經實現

 

EF + Identity實現

EF實現

首先咱們添加一個Data文件夾,因爲VSCode的代碼提示不是很好,接下來咱們用VS2017開發。

咱們首先在Models文件夾下面新建ApplicationUser.cs與ApplicationUserRole.cs

ApplicationUser.cs代碼:

複製代碼
using Microsoft.AspNetCore.Identity;

namespace MvcCookieAuthSample.Models
{
    public class ApplicationUser:IdentityUser<int>//不加int的話是默認主鍵爲guid
    {
    }
}
複製代碼

ApplicationUserRole.cs代碼:

複製代碼
using Microsoft.AspNetCore.Identity;

namespace MvcCookieAuthSample.Models
{
    public class ApplicationUserRole: IdentityRole<int>//不加int的話是默認主鍵爲guid
    {
    }
}
複製代碼

而後在Data文件夾下新建一個ApplicationDbContext.cs類,使它繼承IdentityDbContext

複製代碼
using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore;
using MvcCookieAuthSample.Models;

namespace MvcCookieAuthSample.Data
{
    public class ApplicationDbContext:IdentityDbContext<ApplicationUser, ApplicationUserRole,int>
    {
        public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options):base(options)
        {

        }
    }
}
複製代碼

而後咱們須要在Startup.cs添加EF的註冊進來

//使用配置ApplicationDbContext使用sqlserver數據庫,並配置數據庫鏈接字符串
services.AddDbContext<ApplicationDbContext>(options=> {
    options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection"));
});

而後咱們須要在appsettings.json中配置數據庫鏈接字符串

"ConnectionStrings": {
  "DefaultConnection": "Server=192.168.1.184;Database=aspnet-IdentitySample-9A22BB3E-8D53-4F44-B533-2EF927C959DE;Trusted_Connection=True;MultipleActiveResultSets=true;uid=sa;pwd=123456"
}

EF實現結束

Identity實現

咱們須要在Startup.cs添加Identity的註冊進來

//配置Identity
services.AddIdentity<ApplicationUser, ApplicationUserRole>()
    .AddEntityFrameworkStores<ApplicationDbContext>()
    .AddDefaultTokenProviders();

因爲默認的Identity在密碼上限制比較嚴格,咱們把它改的寬鬆簡單一點(不設置也行)

複製代碼
//修改Identity配置
services.Configure<IdentityOptions>(options =>
{
    options.Password.RequireLowercase = false;//須要小寫
    options.Password.RequireNonAlphanumeric = false;//須要字母
    options.Password.RequireUppercase = false;//須要大寫
});
複製代碼

而後咱們把認證的地址改爲/Account/Login

而後咱們修改AccountController,加入如下代碼

複製代碼
private UserManager<ApplicationUser> _userManager;//建立用戶的
private SignInManager<ApplicationUser> _signInManager;//用來登陸的

//依賴注入
public AccountController(UserManager<ApplicationUser> userManager, SignInManager<ApplicationUser> signInManager)
{
    _userManager = userManager;
    _signInManager = signInManager;
}


[HttpPost]
public async Task<IActionResult> Register(RegisterViewModel registerViewModel)
{
    var identityUser = new ApplicationUser
    {
        Email = registerViewModel.Email,
        UserName = registerViewModel.Email,
        NormalizedUserName = registerViewModel.Email
    };
    var identityResult=await _userManager.CreateAsync(identityUser, registerViewModel.Password);
    if (identityResult.Succeeded)
    {
        return RedirectToAction("Index", "Home");
    }

    return View();
}
複製代碼

 

完整的AccountController

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using MvcCookieAuthSample.Models;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.Cookies;
using System.Security.Claims;
using MvcCookieAuthSample.ViewModels;
using Microsoft.AspNetCore.Identity;

namespace MvcCookieAuthSample.Controllers
{

public class AccountController : Controller
{
private UserManager<ApplicationUser> _userManager;//建立用戶的
private SignInManager<ApplicationUser> _signInManager;//用來登陸的

//依賴注入
public AccountController(UserManager<ApplicationUser> userManager, SignInManager<ApplicationUser> signInManager)
{
_userManager = userManager;
_signInManager = signInManager;
}


public IActionResult Register()
{
return View();
}

[HttpPost]
public async Task<IActionResult> Register(RegisterViewModel registerViewModel)
{
var identityUser = new ApplicationUser
{
Email = registerViewModel.Email,
UserName = registerViewModel.Email,
NormalizedUserName = registerViewModel.Email
};
var identityResult=await _userManager.CreateAsync(identityUser, registerViewModel.Password);
if (identityResult.Succeeded)
{
return RedirectToAction("Index", "Home");
}

return View();
}

public IActionResult Login()
{
return View();
}

 

//登錄
public IActionResult MakeLogin()
{
var claims=new List<Claim>(){
new Claim(ClaimTypes.Name,"wyt"),
new Claim(ClaimTypes.Role,"admin")
};

var claimIdentity= new ClaimsIdentity(claims,CookieAuthenticationDefaults.AuthenticationScheme);

HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme,new ClaimsPrincipal(claimIdentity));

return Ok();
}

//登出
public IActionResult Logout()
{
HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);

return Ok();
}
}
}

 

接下來咱們從新生成一下,咱們須要執行shell命令生成一下數據庫,只有添加  Microsoft.EntityFrameworkCore.Tools  纔會生成成功,不然會報如下錯誤

執行命令老是提示 未找到與命令「dotnet-ef」匹配的可執行文件,根據網上的解決辦法引用 Microsoft.EntityFrameworkCore.Tools 問題依舊不能獲得解決。

解決辦法:

右擊項目彈出菜單點擊編輯***.csprog,增長以下配置。

<ItemGroup>
    <DotNetCliToolReference Include="Microsoft.EntityFrameworkCore.Tools.DotNet" Version="2.0.0" />
</ItemGroup>

執行增長配置命令後

這時候Data文件夾下已經有新增的數據庫更新配置文件了

而後咱們執行更新命令,執行成功後咱們就能夠看到數據庫表已經生成了

接下來咱們運行一下網站進行註冊,註冊成功,已經存儲進數據庫

 註冊實現

前面雖然能夠註冊了,可是咱們註冊完成後並無生成Cookies信息。因此咱們要在Register方法中進行登錄生成Cookies

完整的註冊方法以下:

[HttpPost]
public async Task<IActionResult> Register(RegisterViewModel registerViewModel)
{
var identityUser = new ApplicationUser
{
Email = registerViewModel.Email,
UserName = registerViewModel.Email,
NormalizedUserName = registerViewModel.Email
};
var identityResult=await _userManager.CreateAsync(identityUser, registerViewModel.Password);
if (identityResult.Succeeded)
{
//註冊完成登陸生成cookies信息
await _signInManager.SignInAsync(identityUser, new AuthenticationProperties { IsPersistent = true });

return RedirectToAction("Index", "Home");
}

return View();
}

通常來講,若是用戶已經註冊或者登錄了,註冊和登錄按鈕是要隱藏的,因此咱們接下來要修改_Layout.cshtml視圖頁面判斷註冊/登錄按鈕是否應該隱藏

 

完整的_Layout.cshtml代碼:

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>@ViewData["Title"] - MvcCookieAuthSample</title>

<environment include="Development">
<link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.css" />
<link rel="stylesheet" href="~/css/site.css" />
</environment>
<environment exclude="Development">
<link rel="stylesheet" href="https://ajax.aspnetcdn.com/ajax/bootstrap/3.3.7/css/bootstrap.min.css"
asp-fallback-href="~/lib/bootstrap/dist/css/bootstrap.min.css"
asp-fallback-test-class="sr-only" asp-fallback-test-property="position" asp-fallback-test-value="absolute" />
<link rel="stylesheet" href="~/css/site.min.css" asp-append-version="true" />
</environment>
</head>
<body>
<nav class="navbar navbar-inverse navbar-fixed-top">
<div class="container">
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a asp-area="" asp-controller="Home" asp-action="Index" class="navbar-brand">MvcCookieAuthSample</a>
</div>
<div class="navbar-collapse collapse">
<ul class="nav navbar-nav">
<li><a asp-area="" asp-controller="Home" asp-action="Index">Home</a></li>
<li><a asp-area="" asp-controller="Home" asp-action="About">About</a></li>
<li><a asp-area="" asp-controller="Home" asp-action="Contact">Contact</a></li>
</ul>

@if (User.Identity.IsAuthenticated)
{
<form asp-action="Logout" asp-controller="Account" method="post">
<ul class="nav navbar-nav navbar-right">
<li>
<a title="Welcome" asp-controller="Admin" asp-action="Index">@User.Identity.Name</a>
</li>
<li>
<button type="submit" class="btn btn-link navbar-btn navbar-link">Log out</button>
</li>
</ul>
</form>

}
else
{
<ul class="nav navbar-nav navbar-right">
<li><a asp-area="" asp-controller="Account" asp-action="Register">Register</a></li>
<li><a asp-area="" asp-controller="Account" asp-action="Login">Log in</a></li>
</ul>
}


</div>
</div>
</nav>
<div class="container body-content">
@RenderBody()
<hr />
<footer>
<p>&copy; 2018 - MvcCookieAuthSample</p>
</footer>
</div>

<environment include="Development">
<script src="~/lib/jquery/dist/jquery.js"></script>
<script src="~/lib/bootstrap/dist/js/bootstrap.js"></script>
<script src="~/js/site.js" asp-append-version="true"></script>
</environment>
<environment exclude="Development">
<script src="https://ajax.aspnetcdn.com/ajax/jquery/jquery-2.2.0.min.js"
asp-fallback-src="~/lib/jquery/dist/jquery.min.js"
asp-fallback-test="window.jQuery"
crossorigin="anonymous"
integrity="sha384-K+ctZQ+LL8q6tP7I94W+qzQsfRV2a+AfHIi9k8z8l9ggpc8X+Ytst4yBo/hH+8Fk">
</script>
<script src="https://ajax.aspnetcdn.com/ajax/bootstrap/3.3.7/bootstrap.min.js"
asp-fallback-src="~/lib/bootstrap/dist/js/bootstrap.min.js"
asp-fallback-test="window.jQuery && window.jQuery.fn && window.jQuery.fn.modal"
crossorigin="anonymous"
integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa">
</script>
<script src="~/js/site.min.js" asp-append-version="true"></script>
</environment>

@RenderSection("Scripts", required: false)
</body>
</html>

 

這時候登錄的以後的導航欄信息就有了

登錄實現

 咱們接下來實現一下登錄邏輯,咱們首先新建一個HttpPost的Login的Action

複製代碼
[HttpPost]
public async Task<IActionResult> Login(RegisterViewModel loginViewModel)
{
    var user= await _userManager.FindByEmailAsync(loginViewModel.Email);
    if (user==null)
    {
        //異常先不寫,後期統一收集
    }
    //帳號密碼先不作驗證,須要能夠本身寫
    await _signInManager.SignInAsync(user, new AuthenticationProperties { IsPersistent = true });

    return RedirectToAction("Index", "Home");
}
複製代碼

而後咱們把原來的Logout也順便修改一下,不能是return OK();而要跳轉到首頁

複製代碼
//登出
public async Task<IActionResult> Logout()
{
    //HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);
    //return Ok();

    await _signInManager.SignOutAsync();
    return RedirectToAction("Index", "Home");
}
複製代碼

 接下來咱們修改一下Login.cshtml頁面

@{
ViewData["Title"] = "Login";
}

@using MvcCookieAuthSample.ViewModels;
@model RegisterViewModel;

<div class="row">
<div class="col-md-4">
<section>
<form method="post" asp-controller="Account" asp-action="Login">
<h4>Use a local account to log in.</h4>
<hr />

<div class="form-group">
<label asp-for="Email"></label>
<input asp-for="Email" class="form-control" />
</div>

<div class="form-group">
<label asp-for="Password"></label>
<input asp-for="Password" type="password" class="form-control" />
</div>

<div class="form-group">
<button type="submit" class="btn btn-default">Log in</button>
</div>

</form>
</section>
</div>
</div>

接下來咱們能夠運行一下登錄註冊,便可成功登錄後跳轉到首頁,註冊後跳轉卻是首頁

相關文章
相關標籤/搜索