转自:http://www.jianshu.com/p/fde63052a3a5css
本教程会介绍如何在前端JS程序中集成IdentityServer
。由于全部的处理都在前端,咱们会使用一个JS库oidc-client-js, 来处理诸如获取,验证tokens的工做。html
本教程的代码在这里.前端
本教程分为三大块:node
IdentityServer
进行认证IdentityServer
进行认证第一部分,咱们专一在如何前端认证。咱们准备了两个项目,一个是JS前端程序,一个是IdentityServer
.jquery
在Visual Studio中建立一个空Web应用。git
注意项目的URL,后面须要在浏览器中使用:github
在Visual Studio中建立另一个空Web应用程序来托管IdentityServer
.web
切换到项目属性,启用SSL:ajax
提醒
不要忘了把Web程序的启动URL改为https的连接(具体连接参看你项目的SSL URL).数据库
译者注: identityserver3不支持http的网站,必须有SSL保护
IdentityServer is based on OWIN/Katana and distributed as a NuGet package. To add it to the newly created web host, install the following two packages:
IdentityServer是一个OWIN/Katana的中间件,经过Nuget分发。运行下面的命令安装nuget包到IdentityServer
托管程序。
Install-Package Microsoft.Owin.Host.SystemWeb Install-Package IdentityServer3
IdentityServer
须要知道客户端的一些信息,能够经过返回Client
对象集合告诉IdentityServer
.
public static class Clients { public static IEnumerable<Client> Get() { return new[] { new Client { Enabled = true, ClientName = "JS Client", ClientId = "js", Flow = Flows.Implicit, RedirectUris = new List<string> { "http://localhost:56668/popup.html" //请检查端口号,确保和你刚才建立的JS项目同样 }, AllowedCorsOrigins = new List<string> { "http://localhost:56668" }, AllowAccessToAllScopes = true } }; } }
特别注意AllowedCorsOrigins
属性,上面代码的设置,让IdentityServer
接受这个指定网站的认证请求。 译者注: 考虑到安全性, 网站通常不接受不一样域的请求,这里是设置能够接受指定的跨域请求
popup.html
会在后面详细讲解,这里你照样填就行了.
备注 如今这个客户端能够接受任何做用域(AllowAccessToAllScopes
设置为true).在生产环境,必须经过AllowScopes
来限制做用域范围。
接下来,咱们在IdentityServer里硬编码一些用户--一样的,这个能够经过一个简单的C#类来实现。生产环境中,咱们应该从数据库里获取用户信息。 IdentityServer也直接支持ASP.NET 的Identity和MembershipReboot.
public static class Users { public static List<InMemoryUser> Get() { return new List<InMemoryUser> { new InMemoryUser { Username = "bob", Password = "secret", Subject = "1", Claims = new[] { new Claim(Constants.ClaimTypes.GivenName, "Bob"), new Claim(Constants.ClaimTypes.FamilyName, "Smith"), new Claim(Constants.ClaimTypes.Email, "bob.smith@email.com") } } }; } }
最后,咱们加上做用域。 纯粹认证功能,咱们只须要支持标准的OIDC做用域。未来咱们受权API调用,咱们会建立咱们本身的做用域。
public static class Scopes { public static List<Scope> Get() { return new List<Scope> { StandardScopes.OpenId, StandardScopes.Profile }; } }
IdentityServer
是一个OWIN中间件,须要在Startup类中配置。这个教程中,咱们会配置客户端,用户,做用域,认证证书和一些配置选项。
在生产环境须要从windows证书仓库或者其它安全的地方装载证书。简化起见,这个教程咱们把证书文件直接保存在项目中。(演示用的证书能够从 这里下载.下载后直接添加到项目中,并把文件的Copy to Output Directory
property 改成 Copy always
).
关于如何从Azure中装载证书,请看 这里.
public class Startup { public void Configuration(IAppBuilder app) { app.UseIdentityServer(new IdentityServerOptions { SiteName = "Embedded IdentityServer", SigningCertificate = LoadCertificate(), Factory = new IdentityServerServiceFactory() .UseInMemoryUsers(Users.Get()) .UseInMemoryClients(Clients.Get()) .UseInMemoryScopes(Scopes.Get()) }); } private static X509Certificate2 LoadCertificate() { return new X509Certificate2( Path.Combine(AppDomain.CurrentDomain.BaseDirectory, @"bin\Config\idsrv3test.pfx"), "idsrv3test"); } }
完成上面的步骤后,一个全功能的IdentityServer
就行了,你能够浏览探索端点
来了解相信配置信息。
最后不要忘了在Web.config中添加RAMMFAR支持,不然有一些内嵌的资源没法被IIS装载:
<system.webServer> <modules runAllManagedModulesForAllRequests="true" /> </system.webServer>
咱们使用下面的第三方库来简化咱们的JS客户端开发:
咱们经过npm-- the Node.js 前段包管理器--来安装这些前端库. 若是你尚未安装npm, 你能够按照 npm安装说明来安装npm.
npm安装好了后,打开命令行(CMD),转到JSApplication目录下,运行:
$ npm install jquery $ npm install bootstrap $ npm install oidc-client
npm会把上述包按照到默认目录node_modules
.
重要npm包通常不会提交到源码仓库,若是你是从github仓库中克隆代码, 你须要在命令行(cmd)下,转到JSApplication
目录,而后运行npm install
来恢复这几个前端包。
在JSApplication
项目,加入一个基础的Index.html
文件:
<!DOCTYPE html> <html> <head> <title>JS Application</title> <meta charset="utf-8" /> <link rel="stylesheet" href="node_modules/bootstrap/dist/css/bootstrap.css" /> <style> .main-container { padding-top: 70px; } pre:empty { display: none; } </style> </head> <body> <nav class="navbar navbar-inverse navbar-fixed-top"> <div class="container"> <div class="navbar-header"> <a class="navbar-brand" href="#">JS Application</a> </div> </div> </nav> <div class="container main-container"> <div class="row"> <div class="col-xs-12"> <ul class="list-inline list-unstyled requests"> <li><a href="index.html" class="btn btn-primary">Home</a></li> <li><button type="button" class="btn btn-default js-login">Login</button></li> </ul> </div> </div> <div class="row"> <div class="col-xs-12"> <div class="panel panel-default"> <div class="panel-heading">ID Token Contents</div> <div class="panel-body"> <pre class="js-id-token"></pre> </div> </div> </div> </div> </div> <script src="node_modules/jquery/dist/jquery.js"></script> <script src="node_modules/bootstrap/dist/js/bootstrap.js"></script> <script src="node_modules/oidc-client/dist/oidc-client.js"></script> </body> </html>
和 popup.html
文件:
<!DOCTYPE html> <html> <head> <title></title> <meta charset="utf-8" /> </head> <body> <script src="node_modules/oidc-client/dist/oidc-client.js"></script> </body> </html>
由于oidc-client
能够打开一个弹出窗口让用户登陆,因此咱们作了一个popup页面
好了,如今零件已经组装好了,咱们须要加一点逻辑代码让它动起来. 感谢UserManager
JS类,它作了大部分肮脏的工做,咱们只要一点简单代码就好。
// helper function to show data to the user function display(selector, data) { if (data && typeof data === 'string') { data = JSON.parse(data); } if (data) { data = JSON.stringify(data, null, 2); } $(selector).text(data); } var settings = { authority: 'https://localhost:44300', client_id: 'js', popup_redirect_uri: 'http://localhost:56668/popup.html', response_type: 'id_token', scope: 'openid profile', filterProtocolClaims: true }; var manager = new Oidc.UserManager(settings); var user; manager.events.addUserLoaded(function (loadedUser) { user = loadedUser; display('.js-user', user); }); $('.js-login').on('click', function () { manager .signinPopup() .catch(function (error) { console.error('error while logging in through the popup', error); }); });
简单了解一下这些配置项:
authority
是IdentityServer
的入口URL. 经过这个URL,oidc-client
能够查询如何与这个IdentityServer
通讯, 并验证token的有效性。client_id
这是客户端标识,认证服务器用这个标识来区别不一样的客户端。popup_redirect_uri
是使用signinPopup
方法是的重定向URL。若是你不想用弹出框来登录,但愿用户能到主登陆界面登录,那么你须要使用redirect_uri
属性和signinRedirect
方法。response_type
定义响应类型,在咱们的例子中,咱们只须要服务器返回身份令牌scope
定义了咱们要求的做用域filterProtocolClaims
告诉oidc-client过滤掉OIDC协议内部用的声明信息,如: nonce
, at_hash
, iat
, nbf
, exp
, aud
, iss
和 idp
咱们监听处理Login按钮的单击事件,当用户单击登录的时候,打开登录弹出框(signinPopup
). signinPopup
返回一个Promise
。只有收到用户信息并验证经过后才会标记成功。
有两种方式获得identityServer
返回的数据:
userLoaded
事件的参数获得这个例子中,咱们经过events.addUserLoaded·挂载了
userLoaded事件处理函数,把用户信息保存到全局的user对象中。这个对象有:
id_token,
scope和
profile`等属性, 这些属性包含各类用户具体的数据。
popup.html
页面也须要配置下:
new Oidc.UserManager().signinPopupCallback();
登录内部过程:在index.html
页面的UserManager
实例会打开一个弹出框,而后把它重定向到登录页面。当identityServer
认证好用户,把用户信息发回到弹出框,弹出框发现登录已经成功后自动关闭。
代码抄到这里,登录能够工做啦:
你能够把filterProtocolClaims
属性设置为false,看看profile
下面会多出那些声明?
咱们定义了一个email
声明,可是它好像没有在咱们的身份令牌里面?这是由于咱们的JS应用只要了openid
和profile
做用域,没有包括email
声明。
若是JS应用想拿到邮件地址,JS应用必须在UserManager
的scopes
属性中申请获取email
做用域.
在咱们的例子中,咱们首先须要修改IdentityServer
包含Email做用域,代码以下:
public static class Scopes { public static List<Scope> Get() { return new List<Scope> { StandardScopes.OpenId, StandardScopes.Profile, // New scope StandardScopes.Email }; } }
在这个教程中,JS应用不须要改,由于咱们申请了全部的做用域。 可是在生产环境中,咱们应该只返回用户须要的做用域,这种状况下,客户端代码也须要修改。
完成上面的改动后,咱们如今能够看到email
信息啦:
第二部分,咱们演示如何从JS应用中调用受保护的API。
为了调用被保护的API,除了身份令牌,咱们还要从IdentityServer获得访问令牌,并用这个访问令牌调用被保护的API。
在Visual Studio中建立一个空应用程序.
API项目的URL须要指定为 http://localhost:60136
.
在本教程,咱们将建立一个很是简单的API
首先安装下面的nuget包:
Install-Package Microsoft.Owin.Host.SystemWeb -ProjectName Api Install-Package Microsoft.Owin.Cors -ProjectName Api Install-Package Microsoft.AspNet.WebApi.Owin -ProjectName Api Install-Package IdentityServer3.AccessTokenValidation -ProjectName Api
注意 IdentityServer3.AccessTokenValidation
包间接依赖于System.IdentityModel.Tokens.Jwt
.在编写本教程时,若是更新System.IdentityModel.Tokens.Jwt
到5.0.0会致使API项目没法启动: 译者注:在我翻译的时候好像已经解决这个问题了
解决办法是把System.IdentityModel.Tokens.Jwt
降级到4.0.2.xxx版本:
Install-Package System.IdentityModel.Tokens.Jwt -ProjectName Api -Version 4.0.2.206221351
如今让咱们建立Startup
类,并构建OWIN/Katana管道。
public class Startup { public void Configuration(IAppBuilder app) { // Allow all origins app.UseCors(CorsOptions.AllowAll); // Wire token validation app.UseIdentityServerBearerTokenAuthentication(new IdentityServerBearerTokenAuthenticationOptions { Authority = "https://localhost:44300", // For access to the introspection endpoint ClientId = "api", ClientSecret = "api-secret", RequiredScopes = new[] { "api" } }); // Wire Web API var httpConfiguration = new HttpConfiguration(); httpConfiguration.MapHttpAttributeRoutes(); httpConfiguration.Filters.Add(new AuthorizeAttribute()); app.UseWebApi(httpConfiguration); } }
代码很直观,可是咱们仍是仔细看看咱们在管道中用了些什么:
由于JS应用通常都要跨域,因此咱们启用了CORS。咱们容许来自任何网站的跨域请求,在生产中,咱们须要限制一下,改为只容许咱们但愿的网站来跨域请求。
API项目须要验证令牌的有效性,咱们经过IdentityServer3.AccessTokenValidation
包来实现。在指定Authority
属性后,AccessTokenValidation会自动下载元数据并完成令牌验证的设置。
2.2版本之后,IdentityServer实现了introspection endpoint 来验证令牌。这个端点会进行做用域认证,比传统的令牌验证更安全。
最后是WebAPI配置。咱们使用AuthroizeAttribute
来指定全部的API请求都须要认证。
如今咱们来加上一个简单的API方法:
[Route("values")] public class ValuesController : ApiController { private static readonly Random _random = new Random(); public IEnumerable<string> Get() { var random = new Random(); return new[] { _random.Next(0, 10).ToString(), _random.Next(0, 10).ToString() }; } }
咱们在IdentityServer
项目中的Scopes
增长一个api
做用域:
public static class Scopes { public static List<Scope> Get() { return new List<Scope> { StandardScopes.OpenId, StandardScopes.Profile, StandardScopes.Email, // New scope registration new Scope { Name = "api", DisplayName = "Access to API", Description = "This will grant you access to the API", ScopeSecrets = new List<Secret> { new Secret("api-secret".Sha256()) }, Type = ScopeType.Resource } }; } }
新的做用域是资源做用域,也就是说它会在访问令牌中体现。固然例子中的JS应用不须要修改,由于它请求了所有做用域,可是在生产环境中,应该限制申请那些做用域。
如今咱们更新JS应用,申请新的api
做用域
var settings = { authority: 'https://localhost:44300', client_id: 'js', popup_redirect_uri: 'http://localhost:56668/popup.html', // We add `token` to specify we expect an access token too response_type: 'id_token token', // We add the new `api` scope to the list of requested scopes scope: 'openid profile email api', filterProtocolClaims: true };
修改包括:
response_type
来同时请求身份令牌和访问令牌api
做用域access_token
属性获取,过时时间放在expires_at
属性上。oidc-client
会处理签名证书,令牌验证等麻烦的部分,咱们不须要编写任何代码。登录之后咱们会获得下面的信息:
拿到访问令牌,咱们就能够在JS应用里调用API了。
[...] <div class="container main-container"> <div class="row"> <div class="col-xs-12"> <ul class="list-inline list-unstyled requests"> <li><a href="index.html" class="btn btn-primary">Home</a></li> <li><button type="button" class="btn btn-default js-login">Login</button></li> <!-- New button to trigger an API call --> <li><button type="button" class="btn btn-default js-call-api">Call API</button></li> </ul> </div> </div> <div class="row"> <!-- Make the existing sections 6-column wide --> <div class="col-xs-6"> <div class="panel panel-default"> <div class="panel-heading">User data</div> <div class="panel-body"> <pre class="js-user"></pre> </div> </div> </div> <!-- And add a new one for the result of the API call --> <div class="col-xs-6"> <div class="panel panel-default"> <div class="panel-heading">API call result</div> <div class="panel-body"> <pre class="js-api-result"></pre> </div> </div> </div> </div> </div>
[...] $('.js-call-api').on('click', function () { var headers = {}; if (user && user.access_token) { headers['Authorization'] = 'Bearer ' + user.access_token; } $.ajax({ url: 'http://localhost:60136/values', method: 'GET', dataType: 'json', headers: headers }).then(function (data) { display('.js-api-result', data); }).catch(function (error) { display('.js-api-result', { status: error.status, statusText: error.statusText, response: error.responseJSON }); }); });
代码改好了,咱们如今有一个调用API的按钮和一个显示API结果的Panel。
注意,访问令牌会放到Authroization
请求头里。
登陆前调用,结果以下:
登录后调用,结果以下:
登录前访问API,JS应用没有获得访问令牌,因此不会添加Authorization
请求头,那么访问令牌验证中间件不会介入。请求作为未认证的请求发送到API,全局特性AuthroizeAttribute
会拒绝请求,返回`401未受权错误。
登录后访问API, 令牌验证中间件在请求头中发现了Authorization
,把它传给introspection端点验证,收到身份信息及包含的声明。好了,请求带着认证信息流向了Web API,全局特性AuthroizeAttribute
约束知足了,具体的API成功调用。
如今JS应用能够登陆,能够调用受保护的API了。可是,令牌一旦过时,受保护的API又用不了啦。
好消息是,oidc-token-manager
能够配置成在令牌过时前来自动更新访问令牌,无需用户介入。
首先咱们来看看如何让令牌过时,咱们必须缩短过时时间,过时时间是基于客户端的一个设置项,咱们编辑IdentityServer中的Clients
类。
public static class Clients { public static IEnumerable<Client> Get() { return new[] { new Client { Enabled = true, ClientName = "JS Client", ClientId = "js", Flow = Flows.Implicit, RedirectUris = new List<string> { "http://localhost:56668/popup.html" }, AllowedCorsOrigins = new List<string> { "http://localhost:56668" }, AllowAccessToAllScopes = true, AccessTokenLifetime = 10 } }; } }
访问令牌过时时间默认是1小时,咱们把它改为10秒。
如今你登录JS应用后,过10秒钟在访问API,你又会获得401未受权错误啦。
咱们将依赖oidc-client-js
帮咱们自动更新令牌
在oidc-client-js
内部会记录访问令牌的过时时间,并在过时前向IdentityServer发送受权请求来获取新的访问令牌。按照prompt
设置 --默认设置为none, 在会话有效期内,用户不须要从新受权来获得访问令牌--,这些动做是用户不可见的。IdentityServer会返回一个新的访问令牌替代即将过时的旧令牌。
下面是访问令牌过时和更新的设置说明:
accessTokenExpiring
事件在过时前会激发accessTokenExpiringNotificationTime
用来调整accessTokenExpiring
激发时间.默认是过时前60
秒。automaticSilentRenew
,用来在令牌过时前自动更新令牌。silent_redirect_uri
是指获得新令牌后须要重定向到的URL。oidc-client-js
更新令牌的大体步骤以下:
当令牌快过时的时候,oidc-client-js
会建立一个不可见的iframe
,并在其中启动要给新的受权请求,若是请求成功,identityServer会让iframe重定向到silent_redirect_uri
指定的URL,这部分的的JS代码会自动更新全局用户信息,这样主窗口就能够获得更新后的令牌。
理论讲完了,咱们如今来按照上述内容改代码:
var settings = { authority: 'https://localhost:44300', client_id: 'js', popup_redirect_uri: 'http://localhost:56668/popup.html', // Add the slient renew redirect URL silent_redirect_uri: 'http://localhost:56668/silent-renew.html' response_type: 'id_token token', scope: 'openid profile email api', // Add expiration nofitication time accessTokenExpiringNotificationTime: 4, // Setup to renew token access automatically automaticSilentRenew: true, filterProtocolClaims: true };
silent_redirect_uri
须要一个页面来处理更新用户信息,代码以下:
<!DOCTYPE html> <html> <head> <title></title> <meta charset="utf-8" /> </head> <body> <script src="node_modules/oidc-client/dist/oidc-client.js"></script> <script> new Oidc.UserManager().signinSilentCallback(); </script> </body> </html>
如今须要告诉IdentityServer,新的重定向地址也是合法的。
public static class Clients { public static IEnumerable<Client> Get() { return new[] { new Client { Enabled = true, ClientName = "JS Client", ClientId = "js", Flow = Flows.Implicit, RedirectUris = new List<string> { "http://localhost:56668/popup.html", // The new page is a valid redirect page after login "http://localhost:56668/silent-renew.html" }, AllowedCorsOrigins = new List<string> { "http://localhost:56668" }, AllowAccessToAllScopes = true, AccessTokenLifetime = 70 } }; } }
当更新成功,UserManager
会触发一个userLoaded
事件,由于咱们在前面已经写好了事件处理器,更新的数据会自动显示在UI上。
当失败的时候,silentRenewError
事件会触发,咱们能够订阅这个事件来了解具体什么错了。
manager.events.addSilentRenewError(function (error) { console.error('error while renewing the access token', error); });
咱们把访问令牌生存期设置为10秒,并告诉oidc-client-js
过时前4秒更新令牌。
如今登录之后,每6秒会向identityserver请求更新访问令牌一次。
前端程序的登出和服务端程序的登出不同,好比,你在浏览器里刷新页面,访问令牌就丢失了,你须要从新登录。可是当登录弹出框打开时,它发现你还有一个IdentityServer的有效会话Cookie,因此它不会问你要用户名密码,反而马上关闭本身。整个过程和自动后台更新令牌差很少。
真正的登出意味着从IdentityServer登出,下次进入由IdentityServer保护的程序时,必须从新输入用户名密码。
过程不复杂,咱们只须要在登出
按钮事件里面调用UserManager
的signoutRedirect
方法,固然,咱们也须要在IdentityServer
注册登出重定向url:
public static class Clients { public static IEnumerable<Client> Get() { return new[] { new Client { Enabled = true, ClientName = "JS Client", ClientId = "js", Flow = Flows.Implicit, RedirectUris = new List<string> { "http://localhost:56668/popup.html", "http://localhost:56668/silent-renew.html" }, // Valid URLs after logging out PostLogoutRedirectUris = new List<string> { "http://localhost:56668/index.html" }, AllowedCorsOrigins = new List<string> { "http://localhost:56668" }, AllowAccessToAllScopes = true, AccessTokenLifetime = 70 } }; }
[...] <div class="row"> <div class="col-xs-12"> <ul class="list-inline list-unstyled requests"> <li><a href="index.html" class="btn btn-primary">Home</a></li> <li><button type="button" class="btn btn-default js-login">Login</button></li> <li><button type="button" class="btn btn-default js-call-api">Call API</button></li> <!-- New logout button --> <li><button type="button" class="btn btn-danger js-logout">Logout</button></li> </ul> </div> </div>
var settings = { authority: 'https://localhost:44300', client_id: 'js', popup_redirect_uri: 'http://localhost:56668/popup.html', silent_redirect_uri: 'http://localhost:56668/silent-renew.html', // Add the post logout redirect URL post_logout_redirect_uri: 'http://localhost:56668/index.html', response_type: 'id_token token', scope: 'openid profile email api', accessTokenExpiringNotificationTime: 4, automaticSilentRenew: true, filterProtocolClaims: true }; [...] $('.js-logout').on('click', function () { manager .signoutRedirect() .catch(function (error) { console.error('error while signing out user', error); }); });
当点击logout
按钮时,用户会重定向到IdentityServer,因此回话cookie会被清除。
注意,上面图片显示的是IdentityServer的页面,不是JS应用的界面 上面的例子是经过主页面登出,oidc-client-js
提供了一种在弹出框中登出的方式,和登陆差很少,具体的信息能够参考 oidc-client-js
的文档.
JS应用的会话开始于咱们从IdentityServer获得有效的身份令牌。IdentityServer自身也要维护一个会话管理,在响应受权请求的时候会返回一个session_state
。关于OpenID Connect详细规格说明,请参看这里.
有些状况下,咱们想知道用户是否结束了IdentityServer上的回话,好比说,在另一个应用程序中登出引发在IdentityServer上登出。检查的方式是计算 session_state
的值. 若是它和IdentityServer发出来的同样,那么说明用户还处于登录状态。若是变化了,用户就有可能已经登出了,这时候建议启动一次后台登录请求(带上prompt=none
).若是成功,咱们会获得一个新的身份令牌,也说明在IdentityServer上,用户仍是处于登录状态。失败了,则说明用户已经登出了,咱们须要让用户从新登录。
不幸的是,JS应用本身没办法计算session_state
的值,由于session_state
是IdentityServer的cookie,咱们的JS应用没法访问。OpenID的规格 要求装载一个不可见的iframe
调用IdentityServer的checksession端点。JS应用和iframe
能够经过postMessage
API通讯.
这个端点监听来自postMessage
的消息,按要求提供一个简单的页面。传送到端点的数据用来计算会话的哈希值。若是和IdentityServer上的同样,这个页面返回unchanged
值,不然返回changed
值。若是出现错误,则返回error
.
好消息是oidc-client-js
啥都会 O(∩_∩)O.
事实上,默认设置就会监视会话状态。
相关的属性是 monitorSession
.
当用户一登录进来,oidc-clieng-js
就会建立一个不可见的iframe
,这个iframe
会装载identityserver的会话检查端点。
每隔一段时间,这个iframe
都会发送client id 和会话状态给IdentityServer,并检查收到的结果来断定会话是否已经改变。
咱们能够利用oidc-client-js
的日志系统来认识整个过程是如何进行的。默认状况下oidc-client-js
配置的是无操做(no-op)日志记录器,咱们能够简单的让它输出到浏览器控制台。
Oidc.Log.logger = console;
为了减小日志量,咱们增长访问令牌的生存期。
更新令牌会产生大量日志,如今的设置没6秒要来一次,咱们都没有时间来详细检查日志。因此咱们把它改为1分钟。
public static class Clients { public static IEnumerable<Client> Get() { return new[] { new Client { Enabled = true, ClientName = "JS Client", ClientId = "js", Flow = Flows.Implicit, RedirectUris = new List<string> { "http://localhost:56668/popup.html", "http://localhost:56668/silent-renew.html" }, PostLogoutRedirectUris = new List<string> { "http://localhost:56668/index.html" }, AllowedCorsOrigins = new List<string> { "http://localhost:56668" }, AllowAccessToAllScopes = true, // Access token lifetime increased to 1 minute AccessTokenLifetime = 60 } }; }
最后,当用户会话已经改变,自动登陆也没成功。 UserManager
会触发一个userSinedOut
事件,如今让咱们来处理这个事件。
manager.events.addUserSignedOut(function () { alert('The user has signed out'); });
如今从新回到JS应用,登出,打开浏览器控制台,从新登录; 你会发现每隔2秒钟(默认设置)--oidc-client-js
会检查会话是否仍是有效。
如今咱们来证实它按照咱们设想的那样工做,咱们打开一个新的浏览器tab,转到JS应用并登录。如今这两个tab都在检查会话状态。从其中要给tab登出,你会看到另一个tab会显示以下窗口:
做者:灭蒙鸟连接:http://www.jianshu.com/p/fde63052a3a5來源:简书著做权归做者全部。商业转载请联系做者得到受权,非商业转载请注明出处。