65.9K
CodeProject 正在变化。 阅读更多。
Home

集成您的应用程序与 Affinidi 登录的 5 个简单步骤

2024年1月18日

CPOL

6分钟阅读

viewsIcon

5496

学习使用 Affinidi 登录构建安全的 JavaScript 应用程序,实现无密码身份验证并增强用户隐私。

熟悉事物的全新方式

通过 5 个简单步骤,开始使用 Affinidi 信任网络,以增强用户身份管理和数据隐私。

我们正在构建什么

一个简单的 JavaScript 应用程序,已认证的用户能够在此过程中查看身份提供商向应用程序颁发的身份令牌(idToken)。

熟悉什么

此应用程序将使用 OpenID Connect 协议与身份提供商通信,就像社交登录(使用 Google/Facebook/... 登录)一样。应用程序将按照 OIDC 的保证方式从身份提供商接收 idToken。

新增功能

此应用程序的身份提供商将是其用户,而不是第三方系统。当用户请求登录时,他们将被授权使用自己的身份证明自己是谁,而无需依赖密码。

这种安全、高效、保护隐私的全新方式将使该应用程序能够为用户提供更好的个人体验;因为该应用程序不仅可以登录用户,还可以让他们无需任何表单即可注册。

开始之前

  1. 设置 Affinidi Vault 浏览器扩展。此 Vault 将使我们应用程序的用户能够收集、存储和共享他们的身份、他们的数据,并充当他们自己的身份提供商。
    1. 通过 Google Chrome 商店安装 Affinidi Vault 浏览器扩展。

    Affinidi Vault

    1. 点击 Chrome 浏览器扩展中找到的 Affinidi Vault Chrome 扩展。点击开始并提供一个有效的电子邮件地址。如果您之前创建了 Vault 的备份,您可以使用从备份恢复 Vault

    1. 输入发送到您上一步提供的电子邮件地址的 6 位验证码,然后点击验证。

    1. 通过提供安全的密码短语来保护您的 Vault。使用此密码短语解锁您的 Vault。

    最后,您应该会在屏幕上看到您已成功注册 Affinidi Vault。

    Vault 密码短语

    请记住将您的密码短语保存在安全位置,因为如果忘记了,即使有备份也无法找回。如果忘记了,您必须重新安装和重新配置您的 Vault。

  1. 安装 Node.js:这是一个开源 JavaScript 运行时环境,就像您的浏览器用于渲染 JavaScript 应用程序的运行时一样。
  2. 可选地,安装 Affinidi CLI。如果尚未安装,请按照以下指南进行操作。

设置 Affinidi CLI

  1. 如果尚未设置,请在您的机器上下载并安装 NodeJS。

Node 版本

Affinidi CLI 需要 Node 版本 18 及以上

  1. 使用 Node Package Manager (npm) 安装 Affinidi CLI。
    npm install -g @affinidi/cli
  1. 验证安装是否成功。
affinidi --version

#开始构建

步骤 1:设置您的应用程序

在此步骤中,我们将创建包结构,然后将此应用程序转换为 Node.js 应用程序。然后,我们将创建文件 (index.js),它将代表我们的整个应用程序。我们还将创建一个环境文件来保存所有秘密。

最后,我们将安装 node 包,这将帮助我们构建所需的组件。

mkdir hello-world-affinidi-login
cd hello-world-affinidi-login

npm init -y
touch index.js
touch .env

npm install express dotenv passport openid-client express-session

# Why we do need each of these modules
#
# express is a minimalist web framework for Node.js
# dotenv helps loads environment variables from .env, created above
# passport is express-compatible authentication framework for Node.js
# openid-client is Relying-Party implementation for Node.js, which is passport compatible
# express-session is session middleware for express, required by passport

为了创建一个支持身份验证的应用程序,让我们列出所需的结构。我们将在此基础上逐步构建。

文件路径:index.js

//  1. Import required Libraries
//  2. Create an express application and setup session
//  3. Define application end-points
//  4. Start the http server
//  5. Integrate Authentication

步骤 2:实现应用程序的核心逻辑

在此步骤中,我们将根据上面创建的要求构建应用程序的核心逻辑。

文件路径:index.js

//  1. Import required Libraries
const express = require('express');
const passport = require('passport');
const session = require('express-session');
const { Issuer, Strategy } = require('openid-client');
const http = require("http");
require("dotenv").config();

//  2. Create an express application and setup session
const app = express();
app.use(session({
    secret: 'my-secret',
    resave: false ,
    saveUninitialized: false
}));

// 3. Define application end-points
app.get("/", (req, res) => {
    res.send(" Lets build a Unified Digital Identity <br/><br/><a href='/login'> Affinidi Login</a>");
})

app.get('/login',
    function (req, res, next) {
        next();
    },
);

app.get('/login/callback', (req, res, next) => {})

app.get("/protected", (req, res) => {
    res.header("Content-Type", 'application/json');
    res.end("Protected Content for Authenticated Users");
})

// 4. Start the http server
const httpServer = http.createServer(app)
httpServer.listen(8080, () => {
    console.log(`Hello World - Affinidi Login : Up and running on 8080`)
})

为了更好地管理,我们首先创建 3 个环境变量。

文件路径:.env

issuer= #Verifiable Identifier for the issuer of claims, in this case, Affinidi Login 
client_id=  #Public Identifier for our application, issued by Affinidi Login
client_secret= #Secret known to our application

步骤 3:将身份验证集成到应用程序中

在此步骤中,我们将使用 openid-client 为我们的应用程序创建身份验证策略 affinidi-login。然后将此策略提供给 passport 中间件。

// 5. Integrate Authentication
// 5a. Discover Affinidi Login - Issuer
Issuer.discover(process.env.issuer).then(function (oidcIssuer) {
  // 5b. Create a RP-client which can initiate an OIDC flow
  var client = new oidcIssuer.Client({
    client_id: process.env.client_id,
    client_secret: process.env.client_secret,
    redirect_uris: ["https://:8080/login/callback"],
    response_types: ['code'],
    token_endpoint_auth_method: 'client_secret_post'
  });

  // 5c. Provide this strategy to the passport middleware
  passport.use(
    'affinidi-login', new Strategy({ client, passReqToCallback: true }, (req, tokenSet, userinfo, done) => {
      req.session.tokenSet = tokenSet;
      req.session.userinfo = userinfo;
      return done(null, tokenSet.claims());
    }));
});

passport.serializeUser(function (user, done) {
  done(null, user);
});
passport.deserializeUser(function (user, done) {
  done(null, user);
});

步骤 4:创建应用程序路由以使用身份验证

在此步骤中,我们将把上一步中的身份验证集成到我们的应用程序路由中。从登录页 (/),我们将调用 (/login),利用配置的 passport 策略来验证用户。

最终的 index.js 将如下所示

文件路径:index.js

//  1. Import required Libraries
const express = require('express');
const passport = require('passport');
const session = require('express-session');
const { Issuer, Strategy } = require('openid-client');
const http = require("http");
require("dotenv").config();

//  2. Create an express application and setup session
const app = express();
app.use(session({
    secret: 'my-secret',
    resave: false ,
    saveUninitialized: false
}));
app.use(passport.initialize());
app.use(passport.session());

// 3. Define application end-points
app.get("/", (req, res) => {
    res.send(" Lets build a Unified Digital Identity <br/><br/><a href='/login'> Affinidi Login</a>");
})

app.get('/login',
    function (req, res, next) {
        next();
    },
    passport.authenticate('affinidi-login',{scope:'openid'})
);

app.get('/login/callback', (req, res, next) => {
    passport.authenticate('affinidi-login', {successRedirect: '/protected', failureRedirect: '/'})(req,res,next)
})

app.get("/protected", (req, res) => {
    res.header("Content-Type", 'application/json');
    res.end(JSON.stringify(req.user, null, 4));
})

// 4. Start the http server
const httpServer = http.createServer(app)
httpServer.listen(8080, () => {
    console.log(`Hello World - Affinidi Login : Up and running on 8080`)
})

// 5. Integrate Authentication
// 5a. Discover Affinidi Login - Issuer
Issuer.discover(process.env.issuer).then(function (oidcIssuer) {
    // 5b. Create a RP-client which can initiate an OIDC flow
    var client = new oidcIssuer.Client({
      client_id: process.env.client_id,
      client_secret: process.env.client_secret,
      redirect_uris: ["https://:8080/login/callback"],
      response_types: ['code'],
      token_endpoint_auth_method: 'client_secret_post'
    });
  
    // 5c. Provide this strategy to the passport middleware
    passport.use(
      'affinidi-login', new Strategy({ client, passReqToCallback: true }, (req, tokenSet, userinfo, done) => {
        req.session.tokenSet = tokenSet;
        req.session.userinfo = userinfo;
        return done(null, tokenSet.claims());
      }));
  });
  
  passport.serializeUser(function (user, done) {
    done(null, user);
  });
  passport.deserializeUser(function (user, done) {
    done(null, user);
  });

步骤 5:集成 Affinidi 登录并运行您的应用程序

到目前为止,我们已经构建了一个应用程序,它可以启动 OIDC 流程与 OpenIDProvider,验证用户并接收身份令牌。然后此令牌显示在 (/protected) 页面上。

为了使此应用程序能够利用 Affinidi 登录,我们需要创建一个登录配置。为此,您可以使用 Affinidi CLI 或 Affinidi Portal

创建登录配置时,使用 redirect-uri:https://:8080/login/callback。您可以提供您选择的名称,并将其余选项保留为默认值。

使用 Affinidi CLI
  1. 通过运行以下命令登录 Affinidi CLI
affinidi start
  1. 成功登录后,通过运行以下命令创建登录配置
affinidi login create-config \
--name='Hello World App' \
--redirect-uris='https://:8080/login/callback'
  • --name 是您希望您的登录配置的名称。
  • --redirect-uris 是用户成功身份验证后重定向到您的应用程序的 URL。

示例响应

{
  "ari": "ari:identity:ap-southeast-1:687b8872-a618-dt63-8978-e72ac32daeb1:login_configuration/c4f74d936cd31bde1c1fd3c1050bb76s",
  "projectId": "687b8872-a618-4e52-8978-e72ac32daec2",
  "configurationId": "c4f74d936cd31bde1c1fd3c1050bb62d",
  "name": "My Basic App",
  "auth": {
    "clientId": "<AUTH.CLIENT_ID>",
    "clientSecret": "<AUTH.CLIENT_SECRET>",
    "issuer": "https://<PROJECT_ID>.apse1.login.affinidi.io"
  },
  "redirectUris": [
    "..."
  ],
  "clientMetadata": {
    "name": "My Basic App",
    "logo": "https://login.affinidi.com/default-client-logo.svg",
    "origin": "https://example.com"
  },
  "creationDate": "2023-08-11T06:26:37Z",
  "tokenEndpointAuthMethod": "client_secret_post"
}

了解如何使用 Affinidi CLI 管理您的登录配置。

使用 Affinidi Portal

  1. 在服务部分下,转到 Affinidi 登录
  2. 点击“创建登录配置”并提供所需的详细信息。
  • 名称是描述您的登录配置的字符串。
  • 重定向 URI 是用户成功身份验证后重定向到您的应用程序的 URL。
  1. 点击创建并确认所有详细信息是否正确。

  1. 确认详细信息后,会弹出另一个窗口显示您的登录配置的客户端 ID 和客户端密钥。复制生成的客户端凭据,并使用它们与 Affinidi 登录集成。
  2. 复制客户端 ID 和客户端密钥并关闭弹出窗口后,您将重定向回 Affinidi 登录页面。

使用这两种方法中的任何一种之后,您将从响应中收到客户端 ID、客户端密钥和颁发者 (auth.issuer)。在我们在步骤 2 中创建的 .env 文件中替换这些值。

文件路径:.env

client_id=cliEnt0101-07d5-xxxx-1111-d2de03f62456
client_secret=mYsEcReTmYsEcReT
issuer=https://<PROJECT_ID>.apse1.login.affinidi.io

运行应用程序并在 https://:8080 测试集成。

node index.js

摘要

用户身份验证完成后,主页 (/protected) 显示为应用程序使用而颁发的身份令牌。此令牌是根据我们在上面最后一步中创建的登录配置生成的。

这是示例身份令牌。在 custom 节点下是您通过用户同意作为零方数据返回的声明。您直接从应用程序用户那里接收此数据,而不是从第三方系统接收。

{
    "acr": "0",
    "at_hash": "0A1HHZ4xu0Cpv0gLKqnZ_Q",
    "aud": [
        "eed5f015-07d5-1111-893c-d2de03f62456"
    ],
    "auth_time": 1698111980,
    "custom": [
        {
            "type": [
                "VerifiableCredential",
                "Email"
            ]
        },
        {
            "email": "test@gmail.com"
        },
        {
            "did": "did:key:..."
        }
    ],
    "exp": 1698112882,
    "iat": 1698111982,
    "iss": "https://<PROJECT_ID>.apse1.login.affinidi.io",
    "jti": "d96ea1d4-f8d1-aaBB-ccDD-e3d627d1bde9",
    "rat": 1698111949,
    "sid": "26c7c401-xxYY-4cb1-880c-435599ad6b1a",
    "sub": "did:key:..."
}

奖励

假设您想更多地了解您的用户,以便提供更好的服务,而无需用户填写重复的表单并获得更准确的数据。

与其依赖您今天进行的 B2B 集成,受第三方系统提供的数据限制;让我们看看您在这个新世界中如何做同样的事情。

您所需要做的就是修改上面创建的登录配置(即修改演示定义和 idTokenMapping),或者参考此文档,了解如何为您的登录要求自定义演示定义和 ID 令牌映射。

然后呢?就这样,您所需要的全部。

在此处下载示例 JSON 文件。此文件定义了一个登录配置,其中应用程序需要用户 Vault 中的多个用户身份属性,并以特定定义的 idToken 格式。

affinidi login update-config --id=<login-config-id-created-above> --file="profile-pex.json"

再次运行应用程序,查看现在返回到此应用程序的 custom 令牌中的差异。

在这个简单的“Hello-World”中,我们创建了一个应用程序,将其与 Affinidi 登录集成,并通过 5 个简单步骤从用户那里接收了零方数据。作为开发人员,这使您能够构建保护隐私的应用程序,这些应用程序是安全的并尊重用户对自己身份的所有权。更好的是,我们以一种无需改变我们做事方式的方式完成了所有这一切。继续构建。

© . All rights reserved.