欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

asp.net core 系列之用户认证(authentication)

程序员文章站 2022-07-11 08:34:09
ASP.NET Core 的 identity 是一种需要用户登录的会员系统,用户可以创建一个登录信息存储在 Identity 的的账号, 或者也可以使用第三方登录,支持的第三方登录包括:Facebook, Google, Microsoft Account, and Twitter. Identi ......

 

asp.net core 的 identity 是一种需要用户登录的会员系统,用户可以创建一个登录信息存储在 identity 的的账号,

或者也可以使用第三方登录,支持的第三方登录包括:facebook, google, microsoft account, and twitter.

 

identity 使用sql server 存储用户的姓名,密码等数据,当然你也可以选择其他的存储工具进行存储

 

这篇教程,将会讲解如何使用identity进行用户的注册,登录,登出

 

1.创建一个带认证(authentication)的web应用

  • 文件->新建->项目
  • 选择asp.net core web 应用程序,命名webapp1 ,点击确定
  • 然后选择web 应用程序,然后更改身份验证
  • 选择个人用户账号,确定

asp.net core 系列之用户认证(authentication)

asp.net core 系列之用户认证(authentication)

 

生成的项目会提供 asp.net core identity 功能,并且 identity area 会暴露 下面几个 终端(endpoint):

  • /identity/account/login
  • /identity/account/logout
  • /identity/account/manage

2.迁移

观察生成的代码,发现migration已经生成了,只需要更新到数据库

在nuget 程序控制台中,输入:

update-database

 

直接在vs中的视图,打开sql server 对象管理器,查看数据库效果,确认数据库更新成功:

asp.net core 系列之用户认证(authentication)

 

 asp.net core 系列之用户认证(authentication)

 

3.配置 identity 服务(identity service)

服务被添加到了startup下的 configureservices方法中

public void configureservices(iservicecollection services)
{
    services.configure<cookiepolicyoptions>(options =>
    {
        options.checkconsentneeded = context => true;
        options.minimumsamesitepolicy = samesitemode.none;
    });

    services.adddbcontext<applicationdbcontext>(options =>
        options.usesqlserver(
            configuration.getconnectionstring("defaultconnection")));
    services.adddefaultidentity<identityuser>()
        .adddefaultui(uiframework.bootstrap4)
        .addentityframeworkstores<applicationdbcontext>();

  //这里对identity做一些配置 services.configure<identityoptions>(options => { // password settings.密码配置 options.password.requiredigit = true; options.password.requirelowercase = true; options.password.requirenonalphanumeric = true; options.password.requireuppercase = true; options.password.requiredlength = 6; options.password.requireduniquechars = 1; // lockout settings.锁定设置 options.lockout.defaultlockouttimespan = timespan.fromminutes(5); options.lockout.maxfailedaccessattempts = 5; options.lockout.allowedfornewusers = true; // user settings.用户设置 options.user.allowedusernamecharacters = "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789-._@+"; options.user.requireuniqueemail = false; }); services.configureapplicationcookie(options => { // cookie settings 缓存设置 options.cookie.httponly = true; options.expiretimespan = timespan.fromminutes(5); options.loginpath = "/identity/account/login"; options.accessdeniedpath = "/identity/account/accessdenied"; options.slidingexpiration = true; }); services.addmvc().setcompatibilityversion(compatibilityversion.version_2_2); }

 

 4.添加 注册,登录,登录功能

  • 在解决方案的项目上,右键添加->新搭建基架的项目
  • 选择标识,添加
  • 然后选择你想添加的项

asp.net core 系列之用户认证(authentication)

 

 asp.net core 系列之用户认证(authentication)

asp.net core 系列之用户认证(authentication)

这里的数据上下文中需要选中一个数据的,注意

 

之后,会生成相应的一些文件,包括注册,登录,登出

 

5.现在再看下,生成的代码

注册
public async task<iactionresult> onpostasync(string returnurl = null)
{
    returnurl = returnurl ?? url.content("~/");
    if (modelstate.isvalid)
    {
        var user = new identityuser { username = input.email, email = input.email };
        var result = await _usermanager.createasync(user, input.password); //创建账户
  
     if (result.succeeded) { _logger.loginformation("user created a new account with password."); var code = await _usermanager.generateemailconfirmationtokenasync(user); //生成邮箱验证码 var callbackurl = url.page(  //生成验证的回调地址 "/account/confirmemail", pagehandler: null, values: new { userid = user.id, code = code }, protocol: request.scheme); await _emailsender.sendemailasync(input.email, "confirm your email",  //发送邮箱验证邮件 $"please confirm your account by <a href='{htmlencoder.default.encode(callbackurl)}'>clicking here</a>."); await _signinmanager.signinasync(user, ispersistent: false);  //登录 return localredirect(returnurl); } foreach (var error in result.errors) { modelstate.addmodelerror(string.empty, error.description); } } // if we got this far, something failed, redisplay form return page(); }

 

创建成功后,会直接显示登录状态

 

登录
public async task<iactionresult> onpostasync(string returnurl = null)
{
    returnurl = returnurl ?? url.content("~/");

    if (modelstate.isvalid)
    {
        // this doesn't count login failures towards account lockout
        // to enable password failures to trigger account lockout, 
        // set lockoutonfailure: true
        var result = await _signinmanager.passwordsigninasync(input.email,  //密码登录
            input.password, input.rememberme, lockoutonfailure: true);
        if (result.succeeded)  //登录成功
        {
            _logger.loginformation("user logged in.");
            return localredirect(returnurl);
        }
        if (result.requirestwofactor)  //两步验证
        {
            return redirecttopage("./loginwith2fa", new { returnurl = returnurl, rememberme = input.rememberme });
        }
        if (result.islockedout)  //锁定
        {
            _logger.logwarning("user account locked out.");
            return redirecttopage("./lockout");
        }
        else
        {
            modelstate.addmodelerror(string.empty, "invalid login attempt.");
            return page();
        }
    }

    // if we got this far, something failed, redisplay form
    return page();
}

 

登出
public async task<iactionresult> onpost(string returnurl = null)
        {
            await _signinmanager.signoutasync();  //登出
            _logger.loginformation("user logged out.");
            if (returnurl != null)
            {
                return localredirect(returnurl);
            }
            else
            {
                return page();
            }
        }

 

登录页面
@using microsoft.aspnetcore.identity
@inject signinmanager<identityuser> signinmanager
@inject usermanager<identityuser> usermanager

<ul class="navbar-nav">
    @if (signinmanager.issignedin(user))
    {
        <li class="nav-item">
            <a class="nav-link text-dark" asp-area="identity"
               asp-page="/account/manage/index"
               title="manage">hello@user.identity.name!</a>
        </li>
        <li class="nav-item">
            <form class="form-inline" asp-area="identity" asp-page="/account/logout" 
                   asp-route-returnurl="@url.page("/", new { area = "" })" 
                   method="post">
                <button type="submit" class="nav-link btn btn-link text-dark">logout</button>
            </form>
        </li>
    }
    else
    {
        <li class="nav-item">
            <a class="nav-link text-dark" asp-area="identity" asp-page="/account/register">register</a>
        </li>
        <li class="nav-item">
            <a class="nav-link text-dark" asp-area="identity" asp-page="/account/login">login</a>
        </li>
    }
</ul>

 

 6.验证identity

默认的web项目模板允许匿名访问到主页的,为了验证identity,给privacy 页面增加 [authorize] 

using microsoft.aspnetcore.authorization;
using microsoft.aspnetcore.mvc.razorpages;

namespace webapp1.pages
{
  [authorize] public class privacymodel : pagemodel { public void onget() { } } }

 

7.运行

测试注册,登录,登出功能

以及认证效果对比(即privacy页面增加authrize前后):

加之前:不需要登录,即可访问privacy页面

加之后:需要登录,才能访问此页面

 

这里先记录添加identity操作流程,之后会具体讲解一些功能点