lukeautry / tsoa

Build OpenAPI-compliant REST APIs using TypeScript and Node
MIT License
3.46k stars 497 forks source link

Feature request: For Hapi, generate and use authentication schemes #959

Open icopp opened 3 years ago

icopp commented 3 years ago

Sorting

Expected Behavior

To play nice with other tooling in the Hapi ecosystem, generated Hapi routes should use native Hapi authentication schemes.

Current Behavior

Generated Hapi routes use pre-route hooks that don't leverage the native Hapi authentication functionality.

Possible Solution

Generated code could look very roughly something like this.

The generated auth scheme would only need to be registered once and then could be referenced multiple times, allowing for other tooling to display auth names for each route matching the OpenAPI generated docs.

server.auth.scheme('tsoa', function (server, options) {
  return {
    authenticate: function (request, reply) {
      // ... code wrapping hapiAuthentication goes here

      // error state

      return reply(Boom.unauthorized())

      // valid state

      return reply(null, { 
        // any user credentials info to use elsewhere
        scope: ['admin'] // user's scopes to compare against routes
      })
    },
  }
})

server.auth.strategy('api_key', 'tsoa')
server.auth.strategy('jwt', 'tsoa')

The generated routes would be slightly simpler and would have scope info from @Security embedded in them, again allowing more functionality with other tooling that looks at route metadata.

server.route({
  method: 'GET',
  path: '/',
  options: {
      auth: {
        strategy: 'api_key'
      }
  }
});

server.route({
  method: 'GET',
  path: '/admins',
  options: {
      auth: {
        strategy: 'jwt',
        access: {
          scope: ['admin', 'superuser']
        }
      }
  }
});

Context (Environment)

Version of the library: 3.6.1 Version of NodeJS: 14

Breaking change?

This would be a breaking change in two ways:

WoH commented 3 years ago

I'd have to see the code, but I think it's unlikely this won't be a pain to integrate (esp. bw-compatible) and I don't really see any benefits (based on your feature request). Can you elaborate on why this change would benefit tsoa users?

cheng81 commented 2 years ago

@WoH The main benefit, as far as I understand, would be less "surprises": when I started using tsoa, I too had a kinda bad feeling about the authentication function - it puts the user field into the request object.

While, in the end, it's not a big problem, it also potentially plays bad with existing middlewares for the various frameworks that perhaps expects authentication data in the "proper place". Those would be, as far as I understand:

(*) this requires some thinking, as they are not exposed in controller methods. Perhaps another @AuthenticatedUser decorator?

Lastly, yes I agree, this would be a non backward-compatible change, and it would require a major bump.