【问题标题】:@hapi/bell (discord) --> @hapi/cookie authentication handoff@hapi/bell (discord) --> @hapi/cookie 身份验证切换
【发布时间】:2019-11-20 00:24:07
【问题描述】:

我正在构建一个 hapi(v18.4.0) API,我想根据 Discord OAuth2 服务对用户进行身份验证。我正在使用@hapi/bell(v11.1.0) 来处理 OAuth2 握手。

我可以通过 Discord 进行身份验证,但我无法让 @hapi/cookie(v10.1.2) 接管身份验证职责。我可以看到正在创建 cookie,但我唯一一次看到调用的 cookie validateFunc 函数是使用“注销”路由。我相信我已经为在 localhost 上开发设置了所有必要的标志。

基本上我无法让 cookie 身份验证策略起作用。我很惊讶当我转到需要身份验证的路由时没有看到 validateFunc 被调用。

以下是我的身份验证策略设置、cookie validateFunc 函数、登录/注销路由和测试路由。

感谢您的帮助!

exports.plugin = {
  name: 'auth',
  dependencies: ['hapi-mongodb', 'bell', '@hapi/cookie'],
  register: (server, options) => {

    server.auth.strategy('session', 'cookie', {
      cookie: {
        name: 'sid-demo',
        password: SECRET_KEY,
        isSecure: false,
        isSameSite: 'Lax'
      },
      redirectTo: '/demo-server/api/v1/auth/login', //If there is no session, redirect here
      validateFunc: async (request, session) => {

        console.log("validating cookie...");
        const db = request.mongo.db;
        const ObjectID = request.mongo.ObjectID;

        try {
          const user = await db.collection(usersTable).findOne({ _id: new ObjectID(session.id) });
          if (!user) {
            console.log("no user found, cookie invalid");
            return { valid: false };
          }

          return { valid: true, credentials: user };

        }
        catch (err) {
          console.log("Validation error:", err);
          return { valid: false };        
        }
      }
    });

    server.auth.strategy('discord', 'bell', {
      provider: 'discord',
      password: SECRET_KEY,
      clientId: DISCORD_CLIENT_ID,
      clientSecret: DISCORD_SECRET,
      isSecure: false,
      isSameSite: 'Lax'
    });
  }
};
exports.plugin = {
  name: 'routes-auth',
  dependencies: ['hapi-mongodb', 'auth'],
  register: (server, options) => {

    server.auth.default('session');

    server.route({
      method: ['GET', 'POST'],
      path: '/demo-server/api/v1/auth/login',
      options: {
        auth: 'discord',
        handler: async (request, h) => {

          if (!request.auth.isAuthenticated) {
            console.log("authenticaion failed");
            return `Authentication failed due to: ${request.auth.error.message}`;
          }

          const db = request.mongo.db;

          const credentials = request.auth.credentials;
          const profile = request.auth.credentials.profile;

          try {
            const result = await db.collection(usersTable).findOne({ email: request.auth.credentials.profile.email });
            if (result) {

              console.log("user exists");

              request.cookieAuth.set({
                id: result.id,
                username: profile.username,
                token: credentials.token
              });

              return h.redirect('/demo-server/restricted');
            }
          }
          catch (err) {
            console.log(err);
            return Boom.serverUnavailable('database error');
          }

          console.log("user does not exists, registering new user");
          const user = {
            email: request.auth.credentials.profile.email,
            last_login: new Date(),
            username: request.auth.credentials.profile.username,
          };

          try {

            const result = await db.collection(usersTable).insertOne(user);

            request.cookieAuth.set({
              id: result.insertedId,
              username: profile.username,
              token: credentials.token
            });

          }
          catch (err) {
            return Boom.serverUnavailable('database error');
          }

          return h.redirect('/demo-server/restricted');

        },
        tags: ['auth', 'api']
      }
    });

    server.route({
      method: 'GET',
      path: '/demo-server/api/v1/auth/logout',
      options: {
        handler: (request, h) => {

          request.cookieAuth.clear();
          return h.redirect('/demo-server');
        }
      }
    });
exports.plugin = {
  name: 'routes-default',
  dependencies: ['auth'],
  register: (server, options) => {

    server.route({
      method: 'GET',
      path: '/demo-server',
      handler: (request, h) => {

        return h.response({ result: 'Welcome to demo-server!' }).code(200);
      },
      config: {
        description: 'This is default route for the API.',
        response: {
          status: {}
        },
        tags: ['default','test']
      }
    });

    server.route({
      method: 'GET',
      path: '/demo-server/restricted',
      handler: (request, h) => {

        return h.response({ message: 'Ok, You are authorized.' }).code(200);

      },
      config: {
        auth: {
          mode: 'try'
        },
        description: 'This is a default route used for testing the jwt authentication.',
        response: {
          status: {}
        },
        tags: ['default','test','auth']
      }
    });
  }
};

【问题讨论】:

    标签: cookies oauth hapi


    【解决方案1】:

    发现问题... 我需要将路径设置为 API 的根目录。

    cookie: {
            name: 'sid-demo',
            password: SECRET_KEY, //Use something more secure in production
            path: '/demo-server', // <--- This was what fixed the issue
            isSecure: false,
            isSameSite: 'Lax'
          },
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-02-24
      • 1970-01-01
      • 2020-08-04
      • 1970-01-01
      • 2018-09-24
      • 1970-01-01
      • 2019-11-01
      相关资源
      最近更新 更多