IdentityServer4 中文文档 -15- (快速入门)添加 JavaScript 客户端


    创建一个新的 JavaScript 应用程序项目。这可以是一个简单的空的 Web 项目,或者空的 ASP.NET Core 应用程序。这里将使用空的 ASP.NET Core 应用程序。

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

    选择 “空” 模板:

    15、添加 JavaScript 客户端 - 图2

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

    修改宿主

    修改宿主(像一样)以让应用程序运行在 5003 端口上。

    添加静态文件中间件

    考虑到该项目主要运行于客户端,我们需要 ASP.NET 提供构成应用程序的静态 HTML 和 JavaScript 文件。静态文件中间件被设计来做这些事。 添加 NuGet 程序包 :

    接下来是在 Startup.cs 文件的 Configure 方法中注册静态文件中间件:

    中间件现在将能够从应用程序的 ~/wwwroot 目录提供静态文件 —— 这是我们将要放置 Html 和 JavaScript 文件的地方。

    引用 oidc-client

    在 MVC 项目中,我们使用了一个代码库来处理 OpenID Connect 协议。在该项目中我们也需要一个相似的库,只是这个库要在 JavaScript 中工作并且设计运行于浏览器端。oidc-client 库就是这样一个库,可以通过 ,Bower 等获取到该库,还可以该库。

    如果你想通过 NPM 来下载 oidc-client ,可以按照这些步骤来做:

    15、添加 JavaScript 客户端 - 图4

    package.json 文件的 devDependency 结点中添加一个 oidc-client 引用:

    1. "devDependencies": {
    2. "oidc-client": "1.3.0"
    3. }

    一旦你保存该文件,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> 标签。

    它看起来应该是这样的:

    1. <!DOCTYPE html>
    2. <html>
    3. <head>
    4. <meta charset="utf-8" />
    5. <title></title>
    6. </head>
    7. <body>
    8. <button id="login">Login</button>
    9. <button id="api">Call API</button>
    10. <button id="logout">Logout</button>
    11. <pre id="results"></pre>
    12. <script src="oidc-client.js"></script>
    13. <script src="app.js"></script>
    14. </body>
    15. </html>

    该文件将包含我们应用程序的主要代码。首先我们要在里面添加一个帮助器函数来将消息记录到 <pre> 标签:

    1. function log() {
    2. var results = document.getElementById('results');
    3. results.innerText = '';
    4. Array.prototype.forEach.call(arguments, function (msg) {
    5. if (msg instanceof Error) {
    6. msg = "错误:" + msg.message;
    7. } else if (typeof msg !== 'string') {
    8. msg = JSON.stringify(msg, null, 2);
    9. }
    10. });
    11. }

    然后添加代码,为上述三个按钮注册 “click” 事件处理程序:

    接着我们可以使用 oidc-client 库中的 UserManager 类型来管理 OpenID Connect 协议。它要求与 MVC 客户端中需要的相似的配置(虽然其中的值不尽相同)。添加这些代码以配置和初始化 UserManager

    1. var config = {
    2. authority: 'http://localhost:5000',
    3. client_id: 'js',
    4. redirect_uri: 'http://localhost:5003/callback.html',
    5. response_type: 'id_token token',
    6. scope: 'openid profile api1',
    7. };
    8. var manager = new Oidc.UserManager(config);

    UserManager 提供了一个 getUser API 来确定用户是否已经登录到 JavaScript 应用程序。其用了一个 JavaScript Promise 来返回异步结果。返回的 User 对象具有一个包含用户身份信息的 profile 属性。添加以下代码以检测用户是否已经登录到 JavaScript 应用程序:

    1. manager.getUser().then(function (user) {
    2. if (user) {
    3. log('用户已登录', user.profile);
    4. } else {
    5. log('用户未登录');
    6. }
    7. });

    接下来我们要实现 loginapilogout 等方法。UserManager 提供了 signinRedirect 来登录用户,还提供了 signoutRedirect 来注销用户。在上述代码中我们获取到的 User 对象还有一个 access_token 属性,这可以用来认证到 web API。access_token 将通过 Bearer 模式的 Authorization header 被传递到 web API。添加以下代码以实现我们应用程序中的这三个功能:

    1. function login() {
    2. manager.signinRedirect();
    3. }
    4. function api() {
    5. manager.getUser().then(function (user) {
    6. var url = "http://localhost:5001/identity";
    7. var xhr = new XMLHttpRequest();
    8. xhr.open("GET", url);
    9. xhr.onload = function () {
    10. log(xhr.status, JSON.parse(xhr.responseText));
    11. }
    12. xhr.setRequestHeader("Authorization", "Bearer " + user.access_token);
    13. xhr.send();
    14. });
    15. }
    16. function logout() {
    17. manager.signoutRedirect();
    18. }

    callback.html

    现在客户端应用程序已经准备好运行了,我们需要在 IdentityServer 中为这个新的 JavaScript 客户端定义一个配置入口。在 IdentityServer 项目中定位到客户端配置(在 Config.cs 文件中),然后为我们新的 JavaScript 应用程序向列表中添加新的 Client 定义。配置看起来应该是这样的:

    1. new Client
    2. {
    3. ClientId="js",
    4. AllowedGrantTypes = GrantTypes.Implicit,
    5. AllowAccessTokensViaBrowser=true,
    6. RedirectUris = { "http://localhost:5003/callback.html" },
    7. PostLogoutRedirectUris = { "http://localhost:5003/index.html" },
    8. AllowedCorsOrigins = { "http://localhost:5003" },
    9. AllowedScopes =
    10. {
    11. IdentityServerConstants.StandardScopes.OpenId,
    12. IdentityServerConstants.StandardScopes.Profile,
    13. "api1"
    14. }
    15. }

    允许 Ajax 以 CORS 的方式调用 Web API

    最后需要配置的是 web API 项目中的 CORS。这将允许 Ajax 调用从 http://localhost:5003 跨越到

    添加 Microsoft.AspNetCore.Cors NuGet 程序包。

    15、添加 JavaScript 客户端 - 图6

    配置 CORS

    接着在 Startup.cs 文件的ConfigureServices 方法中将 CORS 服务添加到依赖注入系统:

    1. public void ConfigureServices(IServiceCollection services)
    2. {
    3. services.AddCors(options =>
    4. {
    5. // 这里定义一个 CORS 名为“default”的代理。
    6. options.AddPolicy("default", policy =>
    7. {
    8. policy.WithOrigins("http://localhost:5003")
    9. .AllowAnyHeader()
    10. .AllowAnyMethod();
    11. });
    12. });
    13. services.AddMvcCore()
    14. .AddAuthorization()
    15. .AddJsonFormatters();
    16. }

    最后,在 Configure 方法中将 CORS 中间件添加到管道:

    1. public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
    2. {
    3. loggerFactory.AddConsole(Configuration.GetSection("Logging"));
    4. loggerFactory.AddDebug();
    5. app.UseCors("default");
    6. app.UseIdentityServerAuthentication(new IdentityServerAuthenticationOptions()
    7. {
    8. Authority = "http://localhost:5000",
    9. RequireHttpsMetadata = false,
    10. ApiName = "api1"
    11. });
    12. }

    运行 JavaScript 客户端

    现在你应该能够运行 JavaScript 客户端了:

    点击 “登录” 按钮以登录用户。当用户被返回到 JavaScript 应用程序时,你应该能够看到他们的身份信息:

    15、添加 JavaScript 客户端 - 图8

    然后点击 “调用 API” 以调用 web API:

    最后点击 “注销” 以注销用户。