注意
对于任何先决条件(例如模板),请先查看概述。
本快速入门将展示如何构建基于浏览器的JavaScript客户端应用程序(有时称为“单页应用程序”或“ SPA”)。
用户将登录到IdentityServer,使用由IdentityServer发行的访问令牌调用Web API,然后注销IdentityServer。 所有这些将由浏览器中运行的JavaScript驱动。
JavaScript客户端的新项目
为JavaScript应用程序创建一个新项目。 它可以只是一个空的Web项目,一个空的ASP.NET Core应用程序或其他类似Node.js的应用程序。 本快速入门将使用ASP.NET Core应用程序。
在〜/ src目录中创建一个新的“空” ASP.NET Core Web应用程序。 您可以使用Visual Studio或从命令行执行此操作:
md JavaScriptClient
cd JavaScriptClient
dotnet new web
修改主机
修改JavaScriptClient项目以在端口5003上运行。
添加静态文件中间件
鉴于此项目旨在运行在客户端,因此我们需要ASP.NET Core要做的就是提供将构成我们的应用程序的静态HTML和JavaScript文件。 静态文件中间件就是为此目的而设计的。
在Configure
方法中的Startup.cs
中注册静态文件中间件(并同时删除其他所有内容):
public void Configure(IApplicationBuilder app)
{
app.UseDefaultFiles();
app.UseStaticFiles();
}
现在,该中间件将提供应用程序〜/ wwwroot文件夹中的静态文件。 我们将在此处放置HTML和JavaScript文件。 如果您的项目中不存在该文件夹,请立即创建它。
参考oidc-client
在基于ASP.NET Core MVC的客户端项目中的先前快速入门中,我们使用一个库来处理OpenID Connect协议。 在JavaScriptClient项目的这一快速入门中,我们需要一个类似的库,只是该库可在JavaScript中运行并被设计为在浏览器中运行。 oidc-client library就是这样一种库。 它可以通过NPM,Bower
和从github直接下载获得。
NPM
如果要使用NPM下载oidc-client,请从JavaScriptClient项目目录运行以下命令:
npm i oidc-client
copy node_modules\oidc-client\dist\* wwwroot
这将在本地下载最新的oidc-client软件包,然后将相关的JavaScript文件复制到~/wwwroot中,以便您的应用程序可以使用它们。
说明书下载
如果您只想简单地手动下载oidc-client JavaScript文件,请浏览到GitHub存储库并下载JavaScript文件。 下载后,将它们复制到~/wwwroot,以便您的应用程序可以使用它们。
添加您的HTML和JavaScript文件
接下来是将HTML和JavaScript文件添加到~/wwwroot。 除了oidc-client.js库,我们将有两个HTML文件和一个特定于应用程序的JavaScript文件。 在~/wwwroot中,添加一个名为index.html和callback.html的HTML文件,并添加一个名为app.js的JavaScript文件。
index.html
这将是我们应用程序中的主页。 它仅包含用于用户登录,注销和调用Web API的按钮的HTML。 它还将包含<script>标记,以包含我们的两个JavaScript文件。 它还将包含用于向用户显示消息的<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() {
document.getElementById('results').innerText = '';
Array.prototype.forEach.call(arguments, function (msg) {
if (msg instanceof Error) {
msg = "Error: " + msg.message;
}
else if (typeof msg !== 'string') {
msg = JSON.stringify(msg, null, 2);
}
document.getElementById('results').innerHTML += msg + '\r\n';
});
}
接下来,添加代码以将click
事件处理程序注册到三个按钮:
ocument.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: "code",
scope:"openid profile api1",
post_logout_redirect_uri : "http://localhost:5003/index.html",
};
var mgr = new Oidc.UserManager(config);
接下来,UserManager
提供一个getUser
API,以了解用户是否已登录到JavaScript应用程序。 它使用JavaScript Promise
异步返回结果。 返回的User
对象具有一个profile
文件属性,其中包含该用户的声明。 添加以下代码以检测用户是否登录到JavaScript应用程序:
mgr.getUser().then(function (user) {
if (user) {
log("User logged in", user.profile);
}
else {
log("User not logged in");
}
});
接下来,我们要实现login
,api
和logout
函数。UserManager
提供用于登录用户的signinRedirect
和用于注销用户的signoutRedirect
。 我们在上面的代码中获得的User
对象还具有access_token
属性,可用于对Web API进行身份验证。 access_token
将通过带有承载方案的Authorization标头传递到Web API。 添加以下代码以在我们的应用程序中实现这三个功能:
function login() {
mgr.signinRedirect();
}
function api() {
mgr.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() {
mgr.signoutRedirect();
}
Note
请参阅客户端凭据快速入门 有关如何创建以上代码中使用的api的信息。
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="oidc-client.js"></script>
<script>
new Oidc.UserManager({response_mode:"query"}).signinRedirectCallback().then(function() {
window.location = "index.html";
}).catch(function(e) {
console.error(e);
});
</script>
</body>
</html>
将客户端注册添加到IdentityServer的JavaScript客户端
现在客户端应用程序已准备就绪,我们需要在IdentityServer中为此新的JavaScript客户端定义配置条目。 在IdentityServer项目中,找到客户端配置(在Config.cs中)。 将新客户端添加到我们的新JavaScript应用程序的列表中。 它应该具有下面列出的配置:
// JavaScript Client
new Client
{
ClientId = "js",
ClientName = "JavaScript Client",
AllowedGrantTypes = GrantTypes.Code,
RequirePkce = true,
RequireClientSecret = false,
RedirectUris = { "http://localhost:5003/callback.html" },
PostLogoutRedirectUris = { "http://localhost:5003/index.html" },
AllowedCorsOrigins = { "http://localhost:5003" },
AllowedScopes =
{
IdentityServerConstants.StandardScopes.OpenId,
IdentityServerConstants.StandardScopes.Profile,
"api1"
}
}
允许使用CORS对Web API进行Ajax调用
最后需要进行的配置是在Web API项目中配置CORS。 这将允许从http://localhost:5003到http://localhost:5001进行Ajax调用。
配置CORS
在Startup.cs的ConfigureServices
中将CORS服务添加到依赖项注入系统:
public void ConfigureServices(IServiceCollection services)
{
services.AddControllers();
services.AddAuthentication("Bearer")
.AddIdentityServerAuthentication(options =>
{
options.Authority = "http://localhost:5000";
options.RequireHttpsMetadata = false;
options.ApiName = "api1";
});
services.AddCors(options =>
{
// this defines a CORS policy called "default"
options.AddPolicy("default", policy =>
{
policy.WithOrigins("http://localhost:5003")
.AllowAnyHeader()
.AllowAnyMethod();
});
});
}
在配置中将CORS中间件添加到Configure:
public void Configure(IApplicationBuilder app)
{
app.UseRouting();
app.UseCors("default");
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
运行JavaScript应用程序
现在您应该能够运行JavaScript客户端应用程序:
单击“Login”按钮以登录用户。将用户返回到JavaScript应用程序后,您应该看到其个人资料信息:
然后单击“ API”按钮以调用Web API:
最后单击“Logout”以注销用户。
现在,您将启动一个JavaScript客户端应用程序,该应用程序使用IdentityServer进行登录,注销和验证对Web API的调用。