asp.net core 系列之用户认证(authentication)
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 identity 功能,并且 identity area 会暴露 下面几个 终端(endpoint):
- /identity/account/login
- /identity/account/logout
- /identity/account/manage
2.迁移
观察生成的代码,发现migration已经生成了,只需要更新到数据库
在nuget 程序控制台中,输入:
update-database
直接在vs中的视图,打开sql server 对象管理器,查看数据库效果,确认数据库更新成功:
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.添加 注册,登录,登录功能
- 在解决方案的项目上,右键添加->新搭建基架的项目
- 选择标识,添加
- 然后选择你想添加的项
这里的数据上下文中需要选中一个数据的,注意
之后,会生成相应的一些文件,包括注册,登录,登出
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操作流程,之后会具体讲解一些功能点
上一篇: 鸡蛋做彩绘
下一篇: php miniBB中文乱码问题解决方法
推荐阅读
-
asp.net core 系列之并发冲突的深入理解
-
asp.net core系列之模型绑定和验证方法
-
ASP.NET Core 2.2 : 二十六. 应用JWT进行用户认证及Token的刷新
-
asp.net core 系列之并发冲突的深入理解
-
asp.net core 系列之允许跨域访问2之测试跨域(Enable Cross-Origin Requests:CORS)
-
ASP.NET Core 3.0 一个 jwt 的轻量角色/用户、单个API控制的授权认证库
-
asp.net core 系列之webapi集成Dapper的简单操作教程
-
asp.net core 系列之webapi集成EFCore的简单操作教程
-
ASP.NET CORE系列【六】Entity Framework Core 之数据库迁移
-
asp.net core 系列之允许跨越访问(Enable Cross-Origin Requests:CORS)