Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Authenticating Swagger API docs (drf-yasg)

I've setup DRF-YASG but am unable to figure out how to configure it to show Views that require Authentication.

Below is the configuration.

  schema_view = get_schema_view(
      openapi.Info(
        title="Swagger Doc",
        default_version='v1',
        description="Test description",
        terms_of_service="https://www.google.com/policies/terms/",
        contact=openapi.Contact(email="[email protected]"),
        license=openapi.License(name="BSD License"),
      ),
      validators=['flex', 'ssv'],
      permission_classes=(permissions.AllowAny,),  # If I change the permission it throws an exception. See below
      public=False,
      patterns=public_apis,
  )

the public_apis are the APIs that I want a person to see after they have authenticated themselves.

With the above configuration, it does not show a single API. It only shows the Authorize Button and text that says No operations defined in spec!. But if I change public=False to public=True then it shows all the APIs.

PS: Earlier I was using Django Rest Swagger and I had been able to configure it to show the APIs only after the JWT token had been provided.

Am is using JWT for authentication.

Exception on Permission Change:

Another issue is that if I change the permission above to a DRF Permission class the rendering fails with the error below:

  Internal Server Error: /swagger/
  Traceback (most recent call last):
    File "/usr/local/lib/python3.6/site-packages/django/core/handlers/exception.py", line 41, in inner
      response = get_response(request)
    File "/usr/local/lib/python3.6/site-packages/django/core/handlers/base.py", line 217, in _get_response
      response = self.process_exception_by_middleware(e, request)
    File "/usr/local/lib/python3.6/site-packages/django/core/handlers/base.py", line 215, in _get_response
      response = response.render()
    File "/usr/local/lib/python3.6/site-packages/django/template/response.py", line 107, in render
      self.content = self.rendered_content
    File "/usr/local/lib/python3.6/site-packages/rest_framework/response.py", line 72, in rendered_content
      ret = renderer.render(self.data, accepted_media_type, context)
    File "/usr/local/lib/python3.6/site-packages/drf_yasg/renderers.py", line 54, in render
      self.set_context(renderer_context, swagger)
    File "/usr/local/lib/python3.6/site-packages/drf_yasg/renderers.py", line 62, in set_context
      renderer_context['title'] = swagger.info.title
  AttributeError: 'dict' object has no attribute 'info'
  Internal Server Error: /swagger/

I've tried changing it to permmissions.IsAuthenticated and my own custom permission classes but they all fail with the same error.

like image 335
lukik Avatar asked Feb 08 '18 14:02

lukik


People also ask

How do I add basic authentication to swagger UI?

Basic authentication is easy to define. In the global securityDefinitions section, add an entry with type: basic and an arbitrary name (in this example - basicAuth). Then, apply security to the whole API or specific operations by using the security section.


1 Answers

Turned out the issue was that I was missing rest_framework.authentication.SessionAuthentication in DRF's DEFAULT_AUTHENTICATION_CLASSES.

So the request object sent after logging in via the Django Admin login view did not have a user so all permission classes kept failing and it would then lead to the above error.

So after adding it drf-yasg shows all its glory.

Bug:

The error it throws when this occurs was raised as bug though. See #issue58.

like image 58
lukik Avatar answered Oct 20 '22 09:10

lukik