无法在`hapi.js`中实现JWT授权

问题描述 投票:0回答:1

我有兴趣将 JWT 策略合并到我的 Hapi.js 应用程序的后端中,以增强安全措施并改进身份验证流程。这是我的服务器代码:

const Hapi = require('@hapi/hapi');
const Joi = require('joi');
const Inert = require('inert');
const Vision = require('vision');
const HapiSwaggered = require('hapi-swaggered');
const HapiSwaggeredUI = require('hapi-swaggered-ui');
const knexConfig = require('./knexfile.js')
const knex = require('knex')(knexConfig.development)
const Jwt = require('@hapi/jwt')

const init = async () => {
    const server = Hapi.Server({
        port: 4545,
        host: 'localhost',
        "routes": {
          "cors": {
              "origin": ["*"],
              "headers": ["Accept", "Content-Type"],
              "additionalHeaders": ["X-Requested-With"]
          }
      }
    });



    server.ext('onPreResponse', (request, h) => {
      const response = request.response;
      if (response.isBoom) {
          // Error response, add CORS headers
          response.output.headers['Access-Control-Allow-Origin'] = 'https://hapi.dev';
          response.output.headers['Access-Control-Allow-Header'] = '*';

        } else {
          // Non-error response, add CORS headers
          response.headers['Access-Control-Allow-Origin'] = 'https://hapi.dev';
          response.headers['Access-Control-Allow-Headers'] = '*';

      }
      return h.continue;
    });

    await server.register(Jwt)



    server.auth.strategy('my_jwt_strategy', 'jwt', {
      keys: 'some_shared_secret',
      verify: {
          aud: 'urn:audience:test',
          iss: 'urn:issuer:test',
          sub: false,
          nbf: true,
          exp: true,
          maxAgeSec: 14400, // 4 hours
          timeSkewSec: 15
      },
      validate: (artifacts, request, h) => {
        console.log('Validation: Start');
        console.log('Decoded JWT:', artifacts.decoded);

        // Your validation logic here...

        console.log('Validation: End');

        return { isValid: true }; // Replace with your actual validation result
      }
    
    });




    server.auth.default('my_jwt_strategy');

    server.route({
        method: 'POST',
        path: '/login',
        handler: async (request, h) => {
            // Replace this logic with actual user authentication
            const { username, password } = request.payload;
            if (username === 'exampleUser' && password === 'examplePassword') {
                // Generate JWT token upon successful authentication
                const token = Jwt.token.generate({ user: username }, 'some_shared_secret');
                return { token };
            } else {
                return h.response({ message: 'Invalid credentials' }).code(401);
            }
        },
        options: {
          auth: false
        }
    });

    server.route({
        method: 'POST',
        path: '/register',
        handler: async (request, h) => {
            console.log('requested !')
            // Replace this logic with actual user registration
            const { username, password } = request.payload;
            // Implement user registration logic here, such as saving user to database
            
            // Generate JWT token upon successful registration
            const token = Jwt.token.generate({ user: username }, 'some_shared_secret');
            console.log(token)
            return { token };
        },
        options: {
          auth: false,
          cors: {
            origin: ['*'],
            headers: ['*'],
            credentials: true
          }
        }
    });

    server.route({
      method: 'GET',
      path: '/',
      handler: (request, h) => {
          const headers = request.headers;
          console.log('Request Headers:', headers);
          return 'Hello, World!';
      }
    });



    await server.register([require('./posts/posts_list'), 
                          require('./posts/posts_insert')]);
    await server.register([
        Inert,
        Vision,
        {
          plugin: HapiSwaggered,
          options: {
            info: {
              title: 'Test API Documentation',
              version: '1.0.0',
            },
          },
        },
        {
          plugin: HapiSwaggeredUI,
          options: {
            title: 'Swagger UI',
            path: '/docs', 
          },
        },
      ]);
       

    await server.start();
    console.log('Server started on port 4545 !');
};

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

init();

首先,我发出注册请求并获得如下令牌:

await fetch('http://localhost:4545/register', {
    method: 'POST',
    headers: {
        'Content-Type': 'application/json'
    },
    body: JSON.stringify({username: 'balbalsbd', password: 'asdasdada'})
})
.then(response => {
    if (response.ok) {
        return response.json();
    } else {
        return Promise.reject({ status: response.status, message: response.statusText });
    }
})
.then(data => {
    console.log('Registration successful:', data);
})
.catch(error => {
    console.error('Registration failed:', error);
});

之后,有了这个令牌,我继续通过控制台向路由 / 发送请求,以检查 JWT 的功能,但是,我遇到了 401 错误代码。

await fetch('http://localhost:4545/', {
    method: 'GET',
    headers: {
        'Authorization': `Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyIjoiYXNkc2QiLCJpYXQiOjE3MTExMTM5OTR9.5xND-Cp6G8w89R9Qpc6lWpVzf9CQ9lNM3mCk9EURYhw`
    }
})
.then(response => {
    if (response.ok) {
        return response.json();
    } else {
        return Promise.reject({ status: response.status, message: response.statusText });
    }
})
.then(data => {
    console.log('Response:', data);
})
.catch(error => {
    console.error('Error:', error);
});
javascript jwt hapi.js hapi
1个回答
0
投票

它失败了,因为您生成的 JWT 不包含您正在验证的声明。我会稍微改变一下你的身份验证配置:

server.auth.strategy('my_jwt_strategy', 'jwt', {
    keys: 'some_shared_secret',
    verify: {
        aud: 'urn:audience:test',
        iss: 'urn:issuer:test',
        sub: false,
        nbf: false, // Not before: you probably don't need this in your usecase
        exp: true, // Verify the token isn't expired
        maxAgeSec: 0, // Made redundant by `exp` claim
        timeSkewSec: 0 // You probably don't need to skew your clock.
    },
    validate: (artifacts, request, h) => {
// etc...
Jwt.token.generate(
  { 
      aud: 'urn:audience:test',
      iss: 'urn:issuer:test',
      /**
      * Note: if the username represents a unique id
      * for the user, consider using it as the `sub` claim. **/
      user: username
  },
  'some_shared_secret',
  {
      ttlSec: 14400 // 4 hours, used to set the `exp` claim in the token.
  }
);
© www.soinside.com 2019 - 2024. All rights reserved.