Asp.net core mvc

ASP.NET Core MVC手动添加标识(四)

2019-01-09  本文已影响1人  firechun

标识包含两部分:注册和登录。注册我们已经成功了,现在看看登录。

登录的过程和注册很相似,首先要有一个GET方法来请求登录页面,然后将用户的登录信息提交给同名的POST方法。

在AccountController中添加Login的GET方法。

[HttpGet]
public IActionResult Login(string returnUrl = null)
{
    ViewData["ReturnUrl"] = returnUrl;
    return View();
}

在Models\ViewModels下面添加类LoginViewModel

public class LoginViewModel
{
    [Display(Name = "电子邮箱")]
    public string Email { get; set; }
    [Display(Name = "密码")]
    [DataType(DataType.Password)]
    public string Password { get; set; }
    [Display(Name = "记住我")]
    public bool RememberMe { get; set; }
}

在Views\Account下添加视图,模板选择Create,模型选择LoginViewModel,完成后将按钮文本改为“登录”。

在Views\Shared\_Layout.cshtml中添加登录的链接

<li><a asp-area="" asp-controller="Home" asp-action="Contact">Contact</a></li>
<li><a asp-area="" asp-controller="Account" asp-action="Register">注册</a></li>
<li><a asp-area="" asp-controller="Account" asp-action="Login">登录</a></li>

Ctrl+F5运行测试,测试链接是否正确。当然,现在点“登录”按钮,会出现404,我们还没有添加POST方法。

为了验证用户登录,使用标识框架提供的SignInManager类。修改一下AccountController类。

首先声明一个成员变量:private readonly SignInManager<ApplicationUser> signInManager;

然后在AccountController的构造函数中添加一个参数,并在方法内对成员变量赋值,修改后的构造函数如下:

public AccountController(
            UserManager<ApplicationUser> userManager,
            SignInManager<ApplicationUser> signInManager)
{
    this.userManager = userManager;
    this.signInManager = signInManager;
}

添加Login的POST方法

[HttpPost]
public async Task<IActionResult> Login(LoginViewModel model, string returnUrl = null)
{
    ViewData["ReturnUrl"] = returnUrl;
    if (ModelState.IsValid)
    {
        var result = await signInManager.PasswordSignInAsync(model.Email, model.Password, model.RememberMe, false);
        if (result.Succeeded)
        {
            return RedirectToLocal(returnUrl);
        }
        ModelState.AddModelError(string.Empty, "登录失败!");
    }
    return View(model);
}

Login方法中使用SignInManager类的方法PasswordSignInAsync进行身份验证,这个方法的返回值是SignInResult类型的对象,属性Succeeded表示验证是否成功。登录的业务逻辑和注册的业务逻辑相同,调用标识框架中的方法对用户输入的登录信息进行验证,验证成功重定向到指定页面,否则将错误信息添加到模型验证错误中并返回登录页面。不同的是,SignInResult中没有IdentityErrors属性,不会指出验证失败的原因(比如是用户名错误还是密码错误),所以添加到模型验证错误中的是一段自定义的错误消息。

启动程序,进入登录页面,输入之前注册成功的电子邮箱和密码,如果输入错误,登录页面会显示”登录失败!“的错误信息,否则会返回到主页。

为了更直观地在页面上看到登录是否成功,修改Views\Shared\_Layout.cshtml,在页面代码的顶部加入:

@using Microsoft.AspNetCore.Identity
@using WebTest.Data
@inject SignInManager<ApplicationUser> SignInManager
@inject UserManager<ApplicationUser> UserManager

@inject指令在视图中注入服务,这里把SignInManager和UserManager注入到视图中,使得我们可以在视图中使用它们,就象在AccountController中一样。

修改导航栏部分的代码,将原来添加的“注册”和“登录”菜单改成如下所示:

@if (SignInManager.IsSignedIn(User))
{
    <li><a>欢迎:@UserManager.GetUserName(User)</a></li>
    <li><a asp-controller="Account" asp-action="Logout">注销</a></li>
}
else
{
    <li><a asp-area="" asp-controller="Account" asp-action="Register">注册</a></li>
    <li><a asp-area="" asp-controller="Account" asp-action="Login">登录</a></li>
}

User是当前登录的用户声明(Claim),IsSignedIn用于验证应用程序的Cookie中是否包含当前用户标识。换句话说,也就是当前用户是否登录,如果登录,则使用GetUserName方法获得用户名并显示,同时显示一个“注销”链接,如果没有登录,则仍然显示“注册”和“登录”链接。

在AccountController中添加Logout方法,用于注销用户,方法没有添加特性,默认是GET方法。

public async Task<IActionResult> Logout()
{
    await signInManager.SignOutAsync();
    return RedirectToAction(nameof(HomeController.Index), "Home");
}

运行程序,登录,返回主页后发现并没有显示用户名和“注销”链接,但是用户又确实登录成功了,否则会停留在登录页面并显示错误信息。

现在我们只差最后一步了,要告诉项目我们需要使用标识验证。

修改Startup的方法Configure:

app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseAuthentication();
app.UseCookiePolicy();

没有加粗的代码是创建项目时模板生成的,加粗的这行是我们刚才修改的,务必要将这行代码插入到app.UserCookiePolicy()之前,否则仍然不会成功。

最后运行程序,登录成功后,页面上显示用户名及“注销”链接,点击“注销”,重新显示“注册”和“登录”链接。

上一篇 下一篇

猜你喜欢

热点阅读