学习core登陆认证与跨域资源共享是越不过的砍,因此我在学习中一样也遇到啦这两个问题,今天咱们就用示例来演示下使用下这2个技术点吧.html
本篇主要内容以下:ajax
一、展现一个登陆认证的简单示例json
二、跨域资源访问跨域
三、跨域获取登陆认证的用户信息浏览器
首先咱们实现登陆这个功能,代码以下服务器
[Authorize] public class AccountController : Controller { [HttpGet] [AllowAnonymous] public IActionResult Login(string returnUrl = null) { ViewData["ReturnUrl"] = returnUrl; if (this.User.Identity.IsAuthenticated) { return RedirectPermanent(returnUrl); } return View(); } [HttpPost] [AllowAnonymous] public async Task<IActionResult> Login(string userName, string password,string returnUrl=null) { ViewData["ReturnUrl"] = returnUrl; if (!string.IsNullOrEmpty(userName) && userName == password) { var claims = new List<Claim>(){ new Claim(ClaimTypes.Name,userName),new Claim("password",password),new Claim("realname","张龙豪") }; //init the identity instances var userPrincipal = new ClaimsPrincipal(new ClaimsIdentity(claims, "Customer")); //signin await HttpContext.Authentication.SignInAsync("CookieAuth", userPrincipal, new AuthenticationProperties { ExpiresUtc = DateTime.UtcNow.AddMinutes(20), IsPersistent = false, AllowRefresh = false }); return RedirectPermanent(returnUrl); } else { ViewBag.ErrMsg = "UserName or Password is invalid"; return View(); } }
前台代码以下cookie
<html> <head> <meta name="viewport" content="width=device-width" /> <title>Login</title> </head> <body> <form asp-controller="Account" asp-action="Login" method="post" class="form-horizontal" asp-route-returnurl="@ViewData["ReturnUrl"]" role="form"> <div class="form-group"> <label class="col-md-2 control-label">UserName</label> <div class="col-md-10"> <input type="text" name="username" /> </div> </div> <div class="form-group"> <label class="col-md-2 control-label">Password</label> <div class="col-md-10"> <input type="password" name="password" /> </div> </div> <div class="form-group"> <div class="col-md-offset-2 col-md-10"> <button type="submit" class="btn btn-default">Log in</button> </div> </div> </form> </body> </html>
在Startup文件的Configure方法中加入下面代码app
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline. public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) { app.UseCookieAuthentication(new CookieAuthenticationOptions { AuthenticationScheme = "CookieAuth", //认证方案:这是一个已知中间件的值,当有多个实例的中间件若是你想限制受权到一个实例时这个选项将会起做用。 LoginPath = new PathString("/Account/Login"), //登陆路径:这是当用户试图访问资源但未通过身份验证时,程序将会将请求重定向到这个相对路径。 AccessDeniedPath = new PathString("/Account/Forbidden"), //禁止访问路径:当用户试图访问资源时,但未经过该资源的任何受权策略,请求将被重定向到这个相对路径。 AutomaticAuthenticate = true, //自动认证:这个标志代表中间件应该会在每一个请求上进行验证和重建他建立的序列化主体。 AutomaticChallenge = true, //自动挑战:这个标志标明当中间件认证失败时应该重定向浏览器到登陆路径或者禁止访问路径。 SlidingExpiration = true, //Cookie能够分为永久性的和临时性的。 临时性的是指只在当前浏览器进程里有效,浏览器一旦关闭就失效(被浏览器删除)。 永久性的是指Cookie指定了一个过时时间,在这个时间到达以前,此cookie一直有效(浏览器一直记录着此cookie的存在)。 slidingExpriation的做用是,指示浏览器把cookie做为永久性cookie存储,可是会自动更改过时时间,以使用户不会在登陆后并一直活动,可是一段时间后却自动注销。也就是说,你10点登陆了,服务器端设置的TimeOut为30分钟,若是slidingExpriation为false,那么10:30之后,你就必须从新登陆。若是为true的话,你10:16分时打开了一个新页面,服务器就会通知浏览器,把过时时间修改成10:46。 更详细的说明仍是参考MSDN的文档。 CookieHttpOnly = false //默认为true });
好啦,你能够看到有[Authorize]属性的方法或者控制器都须要登陆才能访问,若是没有登陆是不容许访问的.async
接下来你可能须要获取当前登陆用户的用户信息,代码以下:ide
[HttpPost] public string GetCurrUserRealname() { var s = this.User.Identities.First(u => u.IsAuthenticated).FindFirst("realname").Value; var ss = this.User.Identity.Name; return ss + ":" + s; }
$.post("/Account/GetCurrUserRealname", null, function (data) { $("#content").html(data); });
ok,这样就能获取到当前登陆的用户信息
那如何退出呢?代码以下:
public async Task<JsonResult> Logout() { await HttpContext.Authentication.SignOutAsync("CookieAuth"); return Json(new { data = "验证方案:CookieAuth退出成功" }); }
这样看来完整的登陆验证就完成啦,可是目前位置,个人代码都还简单的要命,只能初学者拿来入手,具体还有不少东西能够扩展.咱们须要本身思考学习.
那这个跨域的环境呢,须要咱们本身搞一下.怎么搞,以下
本地测试前期准备
1.首先咱们搞两个core的站点
2.本地host配置两个域名,并在项目中作以下设置
hosts以下:
网站的launchSettings.json文件中配置项目CoreCorsATest为 "applicationUrl": "http://b.local.com:63455/", 项目AuthentiactionTest为 "applicationUrl": "http://a.local.com:50307/".
3. 实验约定:
咱们在项目AuthentiactionTest中写接口,项目CoreCorsATest中调用AuthentiactionTest中的接口.
不作任何处理写接口跨域调用
AuthentiactionTest中写下以下接口
public class HomeController : Controller { public string GetName() { return "张龙豪"; }
CoreCorsATest中以下调用
$.post("http://a.local.com:50307/Home/GetName", null, function (data) { $("#content").html(data); });
结果以下:接口调用成功,可是跨域资源不容许使用
解决问题
设置跨域的域名
public void ConfigureServices(IServiceCollection services) { //services.AddAuthorization(); // Add framework services. services.AddMvc(); services.AddCors(options => options.AddPolicy("AllowSameDomain", builder => builder.WithOrigins("http://a.local.com:50307", "http://b.local.com:63455"))); }
下面的两种调用方式
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) { app.UseCors("AllowSameDomain");
public class HomeController : Controller { [EnableCors("AllowSameDomain")] public string GetName() { return "张龙豪"; }
这个问题就是上面跨域访问的资源若是出现 [Authorize]特性,或者是访问当前用户的登陆信息,用刚才的方法是不行的.
登陆使用,上述的登陆功能,接口以下
[HttpPost] public string GetCurrUserRealname() { var s = this.User.Identities.First(u => u.IsAuthenticated).FindFirst("realname").Value; var ss = this.User.Identity.Name; return ss + ":" + s; }
那在b.local.com 这个域名下怎么访问才是有效的呢?
须要下面两部操做
1.设置接口服务项目配置,以下操做
services.AddCors(options => options.AddPolicy("AllowSameDomain", builder => builder.WithOrigins("http://a.local.com:50307", "http://b.local.com:63455").AllowCredentials()));
2.ajax访问接口时
$.ajax({ type: 'POST', url: "http://a.local.com:50307/Account/GetCurrUserRealname", data: null, dataType: "json", xhrFields: { withCredentials: true }, success: function (result) { $("#message").html(result); } });
ok,这样就能够访问到当前登陆用户的信息啦
本篇呢,写的都是用例,理论原理,没有涉及,也有一些其余经常使用额扩展点,都没有涉及到.
这里我只是把一些的点,贴出来,但愿对想入手core的同窗有所帮助.若有志同道合者,欢迎加左上方群,一块儿学习进步.