Hapi 框架中使用 hapi-auth-auth0 插件实现 Auth0 身份认证

在前端开发中,身份认证是一个十分重要的问题。Auth0 是一个流行的身份认证解决方案,而 Hapi 则是一个 Node.js 的 Web 应用框架。本文将介绍如何在 Hapi 框架中使用 hapi-auth-auth0 插件来实现 Auth0 身份认证。

安装 hapi-auth-auth0 插件

首先,我们需要在 Hapi 项目中安装 hapi-auth-auth0 插件。可以通过 npm 安装:

配置 Auth0 应用

在使用 hapi-auth-auth0 插件之前,我们需要在 Auth0 中创建一个应用,并配置一些参数。具体步骤如下:

  1. 登录 Auth0 控制台,选择创建一个应用。
  2. 选择“常规 Web 应用”类型,并输入应用名称。
  3. 在“允许登录的域名”中输入 Hapi 应用的域名或 IP 地址,例如“localhost:3000”。
  4. 在“回调 URL”中输入 Hapi 应用的回调 URL,例如“http://localhost:3000/callback”。
  5. 保存应用设置,并记录下“客户端 ID”和“客户端密钥”。

配置 Hapi 服务器

接下来,我们需要在 Hapi 服务器中配置 hapi-auth-auth0 插件。具体步骤如下:

  1. 引入 hapi-auth-auth0 插件:

    const HapiAuthAuth0 = require('hapi-auth-auth0');
  2. 注册插件:

    await server.register(HapiAuthAuth0);
  3. 配置插件:

    server.auth.strategy('auth0', 'auth0', {
        domain: 'YOUR_DOMAIN.auth0.com',
        clientId: 'YOUR_CLIENT_ID',
        clientSecret: 'YOUR_CLIENT_SECRET',
        audience: 'https://YOUR_DOMAIN.auth0.com/api/v2/',
        scope: ['openid', 'profile', 'email']
    });

    其中,各参数的含义如下:

    • domain:Auth0 的域名。例如,如果应用的网址为“https://example.auth0.com”,则 domain 为“example”。
    • clientId:Auth0 应用的客户端 ID。
    • clientSecret:Auth0 应用的客户端密钥。
    • audience:Auth0 API 的地址,用于获取用户信息。
    • scope:授权范围,例如“openid”表示授权身份认证信息,“profile”表示授权用户信息,“email”表示授权用户邮箱信息。

    需要注意的是,domainclientIdclientSecret 都是敏感信息,不应该明文存储在代码中,应该通过环境变量等方式进行配置。

配置路由

最后,我们需要在 Hapi 服务器中配置路由,以实现身份认证和授权。具体步骤如下:

  1. 创建一个登录页面:

    server.route({
        method: 'GET',
        path: '/login',
        handler: (request, h) => {
            return `<a href="/auth0">Log in with Auth0</a>`;
        }
    });
  2. 创建一个回调页面:

    server.route({
        method: 'GET',
        path: '/callback',
        handler: async (request, h) => {
            const { credentials } = await request.auth.authenticate();
            request.cookieAuth.set(credentials);
            return h.redirect('/');
        }
    });

    在这里,我们使用 request.auth.authenticate() 方法来进行身份认证,然后将认证结果保存在 Cookie 中,以便后续使用。

  3. 创建一个需要授权的页面:

    server.route({
        method: 'GET',
        path: '/',
        handler: (request, h) => {
            const { name, picture, email } = request.auth.credentials;
            return `Hello, ${name}! Your email is ${email}.<br><img src="${picture}">`;
        },
        options: {
            auth: 'auth0'
        }
    });

    在这里,我们使用 options.auth 属性来指定需要授权才能访问的路由,即“/”路径。

示例代码

完整的示例代码如下:

const Hapi = require('@hapi/hapi');
const HapiAuthAuth0 = require('hapi-auth-auth0');

const server = Hapi.server({
    port: 3000,
    host: 'localhost'
});

const init = async () => {
    await server.register(HapiAuthAuth0);

    server.auth.strategy('auth0', 'auth0', {
        domain: 'YOUR_DOMAIN.auth0.com',
        clientId: 'YOUR_CLIENT_ID',
        clientSecret: 'YOUR_CLIENT_SECRET',
        audience: 'https://YOUR_DOMAIN.auth0.com/api/v2/',
        scope: ['openid', 'profile', 'email']
    });

    server.auth.default('auth0');

    server.route({
        method: 'GET',
        path: '/login',
        handler: (request, h) => {
            return `<a href="/auth0">Log in with Auth0</a>`;
        }
    });

    server.route({
        method: 'GET',
        path: '/callback',
        handler: async (request, h) => {
            const { credentials } = await request.auth.authenticate();
            request.cookieAuth.set(credentials);
            return h.redirect('/');
        }
    });

    server.route({
        method: 'GET',
        path: '/',
        handler: (request, h) => {
            const { name, picture, email } = request.auth.credentials;
            return `Hello, ${name}! Your email is ${email}.<br><img src="${picture}">`;
        },
        options: {
            auth: 'auth0'
        }
    });

    await server.start();
    console.log(`Server running at: ${server.info.uri}`);
};

process.on('unhandledRejection', (err) => {
    console.log(err);
    process.exit(1);
});

init();

总结

本文介绍了如何在 Hapi 框架中使用 hapi-auth-auth0 插件来实现 Auth0 身份认证。通过本文的介绍,读者可以了解到身份认证的基本原理和实现方式,以及如何在 Hapi 项目中使用 hapi-auth-auth0 插件进行身份认证和授权。同时,本文也提供了完整的示例代码,读者可以参考并应用到自己的项目中。

来源:JavaScript中文网 ,转载请注明来源 本文地址:https://www.javascriptcn.com/post/65c34837add4f0e0ffd80915