scttcper / koa2-swagger-ui

Swagger UI as Koa v2 middleware

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

OAuth2 implicit flow not working

kks010 opened this issue · comments

Hi,
I can't find sufficient information anywhere on the internet regarding a start-to-finish fully working example of OAuth2 using Swagger-UI. I have an OAuth2 server working and when I press the 'authenticate' button in Swagger-UI I'm redirected to the login page, I can log in, and then I am redirected back to Swagger-UI but with the URL now having an access_token value as a query param. My understanding of OAuth is that at this point the access_token should be sent with every subsequent request, but this is not happening. Is Swagger-UI even capable of this automatically? Can it parse the redirected URL and get the access_token and send it in future 'try it out' calls? Is this a manual step that a Swagger-UI user has to complete in order to bridge the gap? I'm sure if I copy and paste this access_token into an api_key security definition I could get it working, but then that amounts to two manual auth steps instead of just one...

Q&A (please complete the following information)
OS: Windows 10
Browser: Chrome
Swagger-UI version: Latest
OpenAPI version: 3.0.0

The codebase for reference:

app.use(
    koaSwagger({
      routePrefix: '/docs',
      swaggerOptions: {
        oauth2RedirectUrl:
          host === 'localhost:8080'
            ? `http://${host}/docs`
            : `https://${host}/docs`,
        deepLinking: true,
        spec: swagger,
      },
    }),
  );


Swagger Code:

const {
  swagger: { host },
} = require('config');
const {
  dip: { url },
} = require('config');

module.exports = {
  openapi: '3.0.0',
  info: {
    title: '',
    description: 'API endpoints with request and responses',
    version: '1.0.0',
  },
  servers: [
    {
      url: host === 'localhost:8080' ? `http://${host}` : `https://${host}`,
      variables: {},
    },
  ],
  security: [
    {
      oAuth2Implicit: [
        'openid',
        'profile',
        'email',
      ],
    },
  ],
  paths: {
    '/products': {
      get: {
        tags: ['Products'],
        summary: 'get all products',
        description: 'Get all products',
        operationId: 'GetAllProducts',
        security: [],
        parameters: [],
        responses: {
          200: {
            description: 'Successful',
          },
          404: {
            description: 'Products not found',
          },
          500: {
            description: 'Internal server error',
          },
        },
        deprecated: false,
      },
    },
    '/productsForAdmin': {
      get: {
        tags: ['Products'],
        summary: 'get all products for admin',
        description: 'Get all products for admin',
        operationId: 'GetAllProductsForAdmin',
        security: [
          {
            oAuth2Implicit: [
              'openid',
              'profile',
              'email',
            ],
          },
        ],
        parameters: [],
        responses: {
          200: {
            description: 'Successful',
          },
          404: {
            description: 'Products not found',
          },
          500: {
            description: 'Internal server error',
          },
        },
        deprecated: false,
      },
    },
  },

  components: {
    securitySchemes: {
      oAuth2Implicit: {
        type: 'oauth2',
        flows: {
          implicit: {
            authorizationUrl: `https://${url}/authorize?audience=https://api.xxxxx.xxx.com`,
            tokenUrl: `https://${url}/oauth/token`,
            response_type: 'token',
            scopes: {
              openid: '',
              profile: '',
              email: '',
            },
          },
        },
      },
    },
    schemas: {
      AuthLoginRequest: {
        title: 'AuthLoginRequest',
        type: 'object',
        properties: {
          email: {
            type: 'string',
          },
          password: {
            type: 'string',
          },
        },
      },
      AuthLoginResponse: {
        title: 'AuthLoginResponse',
        type: 'object',
        properties: {
          authToken: {
            type: 'string',
          },
          id: {
            type: 'string',
          },
        },
      },
    },
  },
};

I have no idea how that works

Hi @scttcper , Can someone else help with this?

I have the same issue with oauth code flow.

Need a route to serve up the oauth-redirect.html page so swagger ui can get the token from the opened window.

I can send a PR. I made changes locally to get it working.

Problem here => this page is missing: https://github.com/swagger-api/swagger-ui/blob/master/dist/oauth2-redirect.html

usually served like this: From Docs

const express = require('express')
const pathToSwaggerUi = require('swagger-ui-dist').absolutePath()

const app = express()

app.use(express.static(pathToSwaggerUi))

app.listen(3000)

OAuth2 settings: From Spec

securityDefinitions: {
    oauth2: {
        type: 'oauth2',
        authorizationUrl:
          'http://127.0.0.1:8080/auth/realms/YOUR-REALM/protocol/openid-connect/auth',
        flow: 'implicit',
        scopes: {
          openid: 'openid',
          profile: 'profile',
        },
      },
}

and

koaSwagger({
   ...otherOptions
   oauthOptions: {
      clientId: 'client-with-implicit-flow-enabled',
      realm: YOUR-REALM,
      appName: 'swagger-ui',
      scopeSeparator: ' ',
      additionalQueryStringParams: { nonce: '132456' },
    }
})

can be easy tested with: Keycloak