添加JavaScript客户端

本快速入门将展示如何构建JavaScript客户端应用程序。用户将登录IdentityServer,使用IdentityServer发出的访问令牌调用Web API,并注销IdentityServer。

JavaScript客户端的新项目

为JavaScript应用程序创建一个新项目。它可以只是一个空的Web项目,也可以是一个空的ASP.NET Core应用程序。此快速入门将使用空的ASP.NET Core应用程序。

创建一个新的ASP.NET Core Web应用程序:

../_images/7_new_project.png

选择“空”模板:

../_images/7_empty_template.png

单击“确定”按钮以创建项目。

修改主机

修改托管(如此处所述)以在端口5003上运行。

添加静态文件中间件

鉴于该项目主要用于客户端,我们需要ASP.NET Core来提供构成我们应用程序的静态HTML和JavaScript文件。静态文件中间件旨在实现此目的。

方法中注册Startup.cs中的静态文件中间件Configure

public void Configure(IApplicationBuilder app)
{
    app.UseDefaultFiles();
    app.UseStaticFiles();
}

此中间件现在将从应用程序的〜/ wwwroot文件夹中提供静态文件这是我们将放置HTML和JavaScript文件的地方。

参考OIDC客户端

在MVC项目中,我们使用库来处理OpenID Connect协议。在这个项目中,我们需要一个类似的库,除了一个在JavaScript中运行并且设计为在浏览器中运行的库。OIDC客户端库就是这样一个图书馆。它可以通过NPMBower以及从github 直接下载

NPM

如果要使用NPM下载oidc-client,请按照以下步骤操作:

将新的NPM包文件添加到项目中并将其命名为package.json

../_images/7_add_package_json.png

的package.json一个补充dependencyoidc-client

"dependencies": {
  "oidc-client": "1.4.1"
}

保存此文件后,Visual Studio应自动将这些包还原到名为node_modules的文件夹中

../_images/7_node_modules.png

〜/ node_modules / oidc-client / dist文件夹中找到名为oidc-client.js文件,并将其复制到应用程序的〜/ wwwroot文件夹中。有更复杂的方法将NPM包复制到〜/ wwwroot,但这些技术超出了本快速入门的范围。

添加HTML和JavaScript文件

接下来是将您的HTML和JavaScript文件添加到〜/ wwwroot我们将有两个HTML文件和一个特定于应用程序的JavaScript文件(除了oidc-client.js库)。〜/ wwwroot中,添加一个名为index.htmlcallback.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”事件处理程序注册到三个按钮:

document.getElementById("login").addEventListener("click", login, false);
document.getElementById("api").addEventListener("click", api, false);
document.getElementById("logout").addEventListener("click", logout, false);

接下来,我们可以使用UserManager类的OIDC客户端库来管理ID连接协议。它需要MVC Client中必需的类似配置(尽管具有不同的值)。添加此代码以配置和实例化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 mgr = new Oidc.UserManager(config);

接下来,UserManager提供getUserAPI以了解用户是否登录到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");
    }
});

接下来,我们要实现的loginapilogout功能。UserManager提供了signinRedirect登录用户,并且signoutRedirect以注销用户。User我们在上面的代码中获得对象还具有access_token可用于通过Web API进行身份验证属性。access_token将被传递给通过网络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();
}

callback.html

redirect_uri一旦用户登录IdentityServer,此HTML文件就是指定的页面。它将完成与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().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.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网络API 

最后一点配置是在Web API项目中配置CORS。这将允许从http:// localhost:5003http:// localhost:5001进行Ajax调用

配置CORS

ConfigureServicesStartup.cs中将CORS服务添加到依赖注入系统

public void ConfigureServices(IServiceCollection services)
{
    services.AddMvcCore()
        .AddAuthorization()
        .AddJsonFormatters();

    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.UseCors("default");

    app.UseAuthentication();

    app.UseMvc();
}

运行JavaScript应用程序

现在您应该能够运行JavaScript客户端应用程序:

../_images/7_not_logged_in.png

单击“登录”按钮以对用户进行签名。一旦用户返回到JavaScript应用程序,您应该看到他们的个人资料信息:

../_images/7_logged_in.png

然后单击“API”按钮以调用Web API:

../_images/7_api_results.png

最后点击“退出”以签署用户。

../_images/7_signed_out.png

您现在可以开始使用IdentityServer进行登录,注销和验证对Web API的调用的JavaScript客户端应用程序。

nidie.com.cn - 用心与你沟通