刘笑吟,p51,朴三肺
asp.net core 的 identity 是一种需要用户登录的会员系统,用户可以创建一个登录信息存储在 identity 的的账号,
或者也可以使用第三方登录,支持的第三方登录包括:facebook, google, microsoft account, and twitter.
identity 使用sql server 存储用户的姓名,密码等数据,当然你也可以选择其他的存储工具进行存储
这篇教程,将会讲解如何使用identity进行用户的注册,登录,登出
生成的项目会提供 asp.net core identity 功能,并且 identity area 会暴露 下面几个 终端(endpoint):
观察生成的代码,发现migration已经生成了,只需要更新到数据库
在nuget 程序控制台中,输入:
update-database
直接在vs中的视图,打开sql server 对象管理器,查看数据库效果,确认数据库更新成功:
服务被添加到了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); }
这里的数据上下文中需要选中一个数据的,注意
之后,会生成相应的一些文件,包括注册,登录,登出
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>
默认的web项目模板允许匿名访问到主页的,为了验证identity,给privacy 页面增加 [authorize]
using microsoft.aspnetcore.authorization; using microsoft.aspnetcore.mvc.razorpages; namespace webapp1.pages {
[authorize] public class privacymodel : pagemodel { public void onget() { } } }
测试注册,登录,登出功能
以及认证效果对比(即privacy页面增加authrize前后):
加之前:不需要登录,即可访问privacy页面
加之后:需要登录,才能访问此页面
这里先记录添加identity操作流程,之后会具体讲解一些功能点
如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复
Net Core Web Api项目与在NginX下发布的方法
asp.net core3.1 引用的元包dll版本兼容性问题解决方案
IdentityServer4实现.Net Core API接口权限认证(快速入门)
ASP.NET Core MVC通过IViewLocationExpander扩展视图搜索路径的实现
网友评论