Skip to content
This repository has been archived by the owner on Jan 11, 2021. It is now read-only.

SECURITY_DEFINITIONS type 'apiKey' isn't compatible with rest_framework.authentication.TokenAuthentication #660

Open
respondcreate opened this issue May 26, 2017 · 9 comments · May be fixed by #662

Comments

@respondcreate
Copy link
Contributor

When using rest_framework.authentication.TokenAuthentication, a token is validated by being in the Authorization header with a keyword, 'Token ', pre-pending the actual token value. If I use the settings below, the token is added to the Authorization header but it is not prepended by 'Token ':

SWAGGER_SETTINGS = {
    'SECURITY_DEFINITIONS': {
        'api_key': {
            'type': 'apiKey',
            'description': 'Personal API Key authorization',
            'name': 'Authorization',
            'in': 'header',
        }
    }
}

This means entering a valid token in the Swagger Authorize button returns a 401 Unauthorized response since requests are sent like this (note the lack of 'Token ' prepending token value in the 'Authorization' header): curl -X POST --header 'Content-Type: application/json' --header 'Accept: application/json' --header 'Authorization: a-token-value' 'http://hostname/api/some-endpoint/'

Is it possible to configure SWAGGER_SETTINGS['SECURITY_DEFINITIONS'] in a way that apiKey/token values are prepended by a keyword (as rest_framework.authentication.TokenAuthentication expects link to relevant code)?

NOTE: Token auth (via the swagger interface) worked this way in the 0.3.10 release (here's a link to where it's happening in the codebase. If this is not possible currently, what would it take to implement this? My guess would be two things:

  1. Add the ability to add a 'keyword' option to the SECURITY_DEFINITIONS (maybe 'key_prefix' which would default to an empty string) which would then be passed along to the swagger view context.
  2. Update the javascript to look for this value and prepend a token value with it. Admittedly my javascript skills aren't the best but if you could show me where I would need to shim the code from the afore-linked example in the paragraph into the current codebase I'd be more than willing to do it.
@respondcreate
Copy link
Contributor Author

Hey @marcgibbons

I did a bit of code-sleuthing and it appears I'd need to shim the keyword in this part of the code into line 1212 (obj.headers[this.name] = this.value;) of rest_framework_swagger/static/rest_framework_swagger/swagger-ui.js. Here's the codeblock in context (I can't link directly to it as github says the file is too big to show in its UI):

else if (this.type === 'header') {
    if(typeof obj.headers[this.name] === 'undefined') {
      obj.headers[this.name] = this.value;
    }

@maxcanada
Copy link

Hi,

After upgrading our version of rest swagger for django, we are facing the same problem. We use TokenAuthentication for our API and whatever I put in the "Authorize" button in the UI, it simply doesn't work.

    'SECURITY_DEFINITIONS': {
        'api_key': {
            'type': 'apiKey',
            'in': 'header',
            'name': 'Authorization'
        }
    },

Those are my settings, pretty common ones.

Is it a bug or is there a way to make the code work with TokenAuthentication?

Currently, all my public APIs endpoints are shown, but none of them requiring authentication.

Best,

@mwatchi
Copy link

mwatchi commented Jun 9, 2017

Same here. I would be willing to live with the token authorization not working, but the fact that it now hides all the API's that require it prevents me from upgrading to this version of DRF swagger.

@dannywillems dannywillems linked a pull request Jun 10, 2017 that will close this issue
@dannywillems
Copy link

@respondcreate @mwatchi @maxcanada See #662. Need to generate the minified JS before merging, and maybe find a better way because it's an ugly hack IMHO.

@respondcreate
Copy link
Contributor Author

Hey @marcgibbons !

Would you mind taking a look at #662 and see if it's OK to merge? Thanks so much for tackling this @dannywillems !!

@respondcreate
Copy link
Contributor Author

Hey @marcgibbons !

Just wanted to ping you again about this issue, any chance you'd be willing to merge this in order to get token auth working via the swagger interface?

@dilipkhemani
Copy link

Hey @marcgibbons !

Were you able to look into this. Has this now been resolved. Unable to use Swagger since the Authorization header needs to be prepended by 'Token'. Thanks in advance.

@maxblax
Copy link

maxblax commented Apr 10, 2018

Hey @marcgibbons
Just wanted an update on this issue. Facing the same problem as I'm using Token base Auth from djoser.
Thank you in advance!

@maxblax
Copy link

maxblax commented Apr 10, 2018

Check answer of https://stackoverflow.com/questions/39547208/django-rest-framework-swagger-authentication-error
It works for me.
Basically
SWAGGER_SETTINGS = {
'SECURITY_DEFINITIONS': {
'api_key': {
# apiKey Type
'type': 'apiKey',
'name': 'Authorization',
'in': 'header'
}
},

"LOGIN_URL": "auth/login/",
"LOGOUT_URL": "auth/logout/"

}

In the docs UI when prompt value enter:
Token

Provided you authentified before, for example manually with:
https::auth/login/

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

6 participants