postgrest-docs icon indicating copy to clipboard operation
postgrest-docs copied to clipboard

swagger-ui

Open wolfgangwalther opened this issue 3 years ago • 2 comments

Discussed in https://github.com/PostgREST/postgrest/discussions/2090

Originally posted by skrick November 18, 2021 What is the "best" way to configure swagger to work with postgrest. I have tried to use docker to link my postgrest and swagger-ui but I cannot figure out how to enable the Bearer security auth. All of my API calls require a valid jwt token.

wolfgangwalther avatar Dec 16 '21 16:12 wolfgangwalther

Hi, @wolfgangwalther, my suggestion would be to utilize nginx as proxy and a static swagger bundle host.

The settings for the nginx would be something along the lines of:

server {
	listen 8080;
	listen [::]:8080 ipv6only=on;

	# Proxy api requests to the PostgREST
	location /api/ {
		# Rewrite Content-Location header
		proxy_hide_header Content-Location;
		add_header  Content-Location  /api$upstream_http_content_location;
		proxy_hide_header Location;
		add_header  Location  /api$upstream_http_location;

                # Add auth button to swagger & rewrite base path
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                proxy_set_header Host $http_host;
                proxy_set_header Accept-Encoding "";

                # Added for swagger support
                # We are going to rewrite the base URL to ensure that we don't expose the Postgres DB
                # and making 8080 proxy the sole entry point.
                sub_filter '0.0.0.0:3000' 'localhost:8080/api';

                # This is what will enable swagger login button -- Add the "securityDefinitions" to the JSON output
                sub_filter '"externalDocs"' '"securityDefinitions":{"JWT":{"type":"apiKey","in":"header","name":"Authorization"}},"security":[{"JWT":[]}],"responses":{"UnauthorizedError":{"description":"Access token is missing or invalid"}},"externalDocs"';
                sub_filter_types application/openapi+json;
                sub_filter_once off;

                proxy_pass http://localhost:3000/;
	}

	# Serve static files or else the single page app
	root /srv/www;  # directory with swagger static bundle
	index index.html;
	location / {
		try_files $uri /index.html =404;
	}

	error_page 404 /not-found;
}

While the static swagger index.html would have this addition:

<script>
    window.onload = function() {
      // Begin Swagger UI call region
      const ui = SwaggerUIBundle({
        url: "/api/",

        dom_id: '#swagger-ui',
        deepLinking: true,
        presets: [
          SwaggerUIBundle.presets.apis,
          SwaggerUIStandalonePreset
        ],
        plugins: [
          SwaggerUIBundle.plugins.DownloadUrl
        ],
        layout: "StandaloneLayout",

        requestInterceptor: (req) => {
          if (!req.loadSpec) {

            // So that user doesn't have to specify Bearer in front of their token
            if (req.headers.Authorization && !req.headers.Authorization.includes('Bearer')) {
              req.headers.Authorization = "Bearer " + req.headers.Authorization;
            }
          }
          return req;
        }
      });

      window.ui = ui;
    };
  </script>

I hope this help you, cheers!

bartekus avatar Feb 10 '22 19:02 bartekus

Also related: https://github.com/PostgREST/postgrest/issues/1082

wolfgangwalther avatar Feb 16 '22 08:02 wolfgangwalther