IdentityServer4 中文文檔 -15- (快速入門)添加 JavaScript 客戶端
原文:http://docs.identityserver.io/en/release/quickstarts/7_javascript_client.html
上一篇:IdentityServer4 中文文檔 -14- (快速入門)使用 ASP.NET Core Identity
下一篇:IdentityServer4 中文文檔 -16- (快速入門)使用 EntityFramework Core 存儲配置數據
該快速入門將展示如何搭建一個 JavaScript 客戶端應用程序,其中的用戶將登陸到 IdentityServer,使用 IdentityServer 發布的訪問令牌調用 Web API,然后從 IdentityServer 注銷。
新的 JavaScript 客戶端項目
創建一個新的 JavaScript 應用程序項目。這可以是一個簡單的空的 Web 項目,或者空的 ASP.NET Core 應用程序。這里將使用空的 ASP.NET Core 應用程序。
創建一個新的 ASP.NET Core Web 應用程序:
選擇 “空” 模板:
點擊“確定”按鈕以創建項目。
修改宿主
修改宿主(像之前描述的一樣)以讓應用程序運行在 5003 端口上。
添加靜態文件中間件
考慮到該項目主要運行於客戶端,我們需要 ASP.NET 提供構成應用程序的靜態 HTML 和 JavaScript 文件。靜態文件中間件被設計來做這些事。 添加 NuGet 程序包 Microsoft.AspNetCore.StaticFiles
:
注冊靜態文件中間件
接下來是在 Startup.cs 文件的 Configure
方法中注冊靜態文件中間件:
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
app.UseDefaultFiles();
app.UseStaticFiles();
}
中間件現在將能夠從應用程序的 ~/wwwroot 目錄提供靜態文件 —— 這是我們將要放置 Html 和 JavaScript 文件的地方。
引用 oidc-client
在 MVC 項目中,我們使用了一個代碼庫來處理 OpenID Connect 協議。在該項目中我們也需要一個相似的庫,只是這個庫要在 JavaScript 中工作並且設計運行於瀏覽器端。oidc-client 庫就是這樣一個庫,可以通過 NPM,Bower 等獲取到該庫,還可以直接從 github 下載該庫。
NPM
如果你想通過 NPM 來下載 oidc-client ,可以按照這些步驟來做:
向你的項目中添加一個新的 NPM 程序包定義文件並命名為 package.json:
在 package.json 文件的 devDependency
結點中添加一個 oidc-client
引用:
"devDependencies": {
"oidc-client": "1.3.0"
}
一旦你保存該文件,Visual Studio 應該會自動還原這些程序包到一個名為 node_modules 的目錄下:
在 ~/node_modules/oidc-client/dist 目錄下找到名為 oidc-client.js 的文件,並將其復制到應用程序的 ~/wwwroot 目錄。有其他更為復雜的方式可以將你的 NPM 程序包復制到 ~/wwwroot
目錄下,但是這些技術超出了當前快速入門的范圍。
添加你的 Html 和 JavaScript 文件
接下來是將你的 HTML 和 JavaScript 文件添加到 ~/wwwroot
目錄下。這里涉及到兩份 HTML 文件和一份面向具體應用程序的 JavaScript 文件(不同於 oidc-client.js 庫的文件)。在 ~/wwwroot 目錄下,添加一份名為 index.html 和一份名為 callback.html 的 HTML 文件,還有一份名為 app.js 的 JavaScript 文件。
index.html
這將是你應用程序的主頁面,它將簡單地包含用於用戶登錄、注銷和調用 Web API 的按鈕,還將包含引用上述兩份 JavaScript 文件的 <script>
標簽和用於向用戶顯示消息的 <pre>
標簽。
它看起來應該是這樣的:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
</head>
<body>
<button id="login">Login</button>
<button id="api">Call API</button>
<button id="logout">Logout</button>
<pre id="results"></pre>
<script src="oidc-client.js"></script>
<script src="app.js"></script>
</body>
</html>
app.js
該文件將包含我們應用程序的主要代碼。首先我們要在里面添加一個幫助器函數來將消息記錄到 <pre>
標簽:
function log() {
var results = document.getElementById('results');
results.innerText = '';
Array.prototype.forEach.call(arguments, function (msg) {
if (msg instanceof Error) {
msg = "錯誤:" + msg.message;
} else if (typeof msg !== 'string') {
msg = JSON.stringify(msg, null, 2);
}
results.innerHTML += msg + '\r\n';
});
}
然后添加代碼,為上述三個按鈕注冊 “click” 事件處理程序:
document.getElementById('login').addEventListener('click', login, false);
document.getElementById('api').addEventListener('click', api, false);
document.getElementById('logout').addEventListener('click', logout, false);
接着我們可以使用 oidc-client 庫中的 UserManager
類型來管理 OpenID Connect 協議。它要求與 MVC 客戶端中需要的相似的配置(雖然其中的值不盡相同)。添加這些代碼以配置和初始化 UserManager
:
var config = {
authority: 'http://localhost:5000',
client_id: 'js',
redirect_uri: 'http://localhost:5003/callback.html',
response_type: 'id_token token',
scope: 'openid profile api1',
post_logout_redirect_uri: 'http://localhost:5003/index.html'
};
var manager = new Oidc.UserManager(config);
UserManager
提供了一個 getUser
API 來確定用戶是否已經登錄到 JavaScript 應用程序。其用了一個 JavaScript Promise
來返回異步結果。返回的 User
對象具有一個包含用戶身份信息的 profile
屬性。添加以下代碼以檢測用戶是否已經登錄到 JavaScript 應用程序:
manager.getUser().then(function (user) {
if (user) {
log('用戶已登錄', user.profile);
} else {
log('用戶未登錄');
}
});
接下來我們要實現 login
、api
、logout
等方法。UserManager
提供了 signinRedirect
來登錄用戶,還提供了 signoutRedirect
來注銷用戶。在上述代碼中我們獲取到的 User
對象還有一個 access_token
屬性,這可以用來認證到 web API。access_token
將通過 Bearer 模式的 Authorization header 被傳遞到 web API。添加以下代碼以實現我們應用程序中的這三個功能:
function login() {
manager.signinRedirect();
}
function api() {
manager.getUser().then(function (user) {
var url = "http://localhost:5001/identity";
var xhr = new XMLHttpRequest();
xhr.open("GET", url);
xhr.onload = function () {
log(xhr.status, JSON.parse(xhr.responseText));
}
xhr.setRequestHeader("Authorization", "Bearer " + user.access_token);
xhr.send();
});
}
function logout() {
manager.signoutRedirect();
}
callback.html
當用戶登錄到 IdentityServer 后,該 HTML 文件是指定的 redirect_uri
頁面,它將完成與 IdentityServer 間 OpenID Connect 協議的登錄握手。之前我們使用的 UserManager
提供了所有實現這些的代碼。一旦登錄完成,我們就可以將用戶重定向回 index.html 主頁面。添加以下代碼以完成登錄過程:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>登錄回調</title>
</head>
<body>
<script src="scripts/oidc-client.js"></script>
<script>
new Oidc.UserManager().signinRedirectCallback().then(function () {
window.location = 'index.html';
}).catch(function (e) {
console.error(e);
});
</script>
</body>
</html>
添加 JavaScript 客戶端定義
現在客戶端應用程序已經准備好運行了,我們需要在 IdentityServer 中為這個新的 JavaScript 客戶端定義一個配置入口。在 IdentityServer 項目中定位到客戶端配置(在 Config.cs 文件中),然后為我們新的 JavaScript 應用程序向列表中添加新的 Client 定義。配置看起來應該是這樣的:
new Client
{
ClientId="js",
ClientName="JavaScript 客戶端",
AllowedGrantTypes = GrantTypes.Implicit,
AllowAccessTokensViaBrowser=true,
RedirectUris = { "http://localhost:5003/callback.html" },
PostLogoutRedirectUris = { "http://localhost:5003/index.html" },
AllowedCorsOrigins = { "http://localhost:5003" },
AllowedScopes =
{
IdentityServerConstants.StandardScopes.OpenId,
IdentityServerConstants.StandardScopes.Profile,
"api1"
}
}
允許 Ajax 以 CORS 的方式調用 Web API
最后需要配置的是 web API 項目中的 CORS。這將允許 Ajax 調用從 http://localhost:5003 跨越到 http://localhost:5001 。
CORS NuGet 程序包
添加 Microsoft.AspNetCore.Cors
NuGet 程序包。
配置 CORS
接着在 Startup.cs 文件的ConfigureServices
方法中將 CORS 服務添加到依賴注入系統:
public void ConfigureServices(IServiceCollection services)
{
services.AddCors(options =>
{
// 這里定義一個 CORS 名為“default”的代理。
options.AddPolicy("default", policy =>
{
policy.WithOrigins("http://localhost:5003")
.AllowAnyHeader()
.AllowAnyMethod();
});
});
services.AddMvcCore()
.AddAuthorization()
.AddJsonFormatters();
}
最后,在 Configure
方法中將 CORS 中間件添加到管道:
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
loggerFactory.AddConsole(Configuration.GetSection("Logging"));
loggerFactory.AddDebug();
app.UseCors("default");
app.UseIdentityServerAuthentication(new IdentityServerAuthenticationOptions()
{
Authority = "http://localhost:5000",
RequireHttpsMetadata = false,
ApiName = "api1"
});
app.UseMvc();
}
運行 JavaScript 客戶端
現在你應該能夠運行 JavaScript 客戶端了:
點擊 “登錄” 按鈕以登錄用戶。當用戶被返回到 JavaScript 應用程序時,你應該能夠看到他們的身份信息:
然后點擊 “調用 API” 以調用 web API:
最后點擊 “注銷” 以注銷用戶。
你現在已經入門了使用 IdentityServer 進行登錄,注銷以及認證 Web API 調用的 JavaScript 客戶端應用程序。
上一篇:IdentityServer4 中文文檔 -14- (快速入門)使用 ASP.NET Core Identity
下一篇:IdentityServer4 中文文檔 -16- (快速入門)使用 EntityFramework Core 存儲配置數據