Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Swagger-UI refuses to add request header #1244

Closed
jaman1020 opened this issue May 6, 2015 · 41 comments
Closed

Swagger-UI refuses to add request header #1244

jaman1020 opened this issue May 6, 2015 · 41 comments

Comments

@jaman1020
Copy link

I've been pulling my hair out on this, not sure if I'm doing something wrong?
I have been unable to get a swagger-ui request to include ANY type of header. My Grape API uses an API token in the header for auth, and no matter what I do I cannot get it to show up in anything. I've tried all of the api-key example code, so I must be doing SOMETHING wrong.

However, upon closer inspection, even the demo petstore app does not contain an api header in the request headers.

screen shot 2015-05-06 at 2 52 21 am

I'm using the readme/sample code verbatim right now -

function addApiKeyAuthorization(){
        var key = encodeURIComponent($('#input_apiKey')[0].value);
        if(key && key.trim() != "") {
            var apiKeyAuth = new SwaggerClient.ApiKeyAuthorization("api_key", key, "query");
            window.swaggerUi.api.clientAuthorizations.add("api_key", apiKeyAuth);
            log("added key " + key);
        }
      }

How can I get a request header of "api_key: value" to show up in request headers?

@webron
Copy link
Contributor

webron commented May 6, 2015

That's probably because of a known bug. Can you try the develop_2.0 branch?

@jaman1020
Copy link
Author

Just tried it and the same thing happened.
Here is the relevant code in index.html -

      function addApiKeyAuthorization(){
        var key = encodeURIComponent($('#input_apiKey')[0].value);
        if(key && key.trim() != "") {
            var apiKeyAuth = new SwaggerClient.ApiKeyAuthorization("api_key", key, "query");
            window.swaggerUi.api.clientAuthorizations.add("api_key", apiKeyAuth);
            log("added key " + key);
        }
      }

      $('#input_apiKey').change(addApiKeyAuthorization);

      // if you have an apiKey you would like to pre-populate on the page for demonstration purposes...

        var apiKey = "myApiKeyXXXX123456789";
        $('#input_apiKey').val(apiKey);
        addApiKeyAuthorization();

and the request headers -
screen shot 2015-05-06 at 3 21 36 am

I've also tried changing apiKeyAuth to 'header' instead of query, no dice

@ponelat
Copy link
Member

ponelat commented May 6, 2015

Yes, a legacy line has been causing some hair-loss.
We've removed a dead line that caused confusion...
#1205
Try after removing that line(s), and if it's still not working - I'll try and replicate.

@jaman1020
Copy link
Author

That fixed the initial crash I was having, but unfortunately still didn't add a header. I'm inspecting the request both on the chrome side and grape side and there's nothing in either

@ponelat
Copy link
Member

ponelat commented May 6, 2015

Ok, I'm going to replicate. You're using the readme example, from develop_2.0?

@ponelat
Copy link
Member

ponelat commented May 6, 2015

The key in the example is a "query" key, meaning it gets attached to url?api_key=some-key.
It looks like it's working on develop_2.0
Try changing "

var apiKeyAuth = new SwaggerClient.ApiKeyAuthorization("api_key", key, "query");
// to this...
var apiKeyAuth = new SwaggerClient.ApiKeyAuthorization("api_key", key, "header"); // <- make it a header key

@ponelat
Copy link
Member

ponelat commented May 6, 2015

We currently support "query" and "header" auth keys, although there is a mechanism to manipulate each request before it gets executed, meaning you can have access to all headers, parameters, etc. Which is a little more "hands on" though.
You should see the request header, if you change the above - I'm testing it with Google Chromes' Network tab.

@jaman1020
Copy link
Author

Not sure what I'm doing wrong, but I still can't see it. I downloaded the develop_2.0 branch and opened ./dist/index.html in chrome. I haven't changed anything but this line in the whole project. This is the entire contents of the script tag -

  <script type="text/javascript">
    $(function () {
      var url = window.location.search.match(/url=([^&]+)/);
      if (url && url.length > 1) {
        url = decodeURIComponent(url[1]);
      } else {
        url = "http://petstore.swagger.io/v2/swagger.json";
      }
      window.swaggerUi = new SwaggerUi({
        url: url,
        dom_id: "swagger-ui-container",
        supportedSubmitMethods: ['get', 'post', 'put', 'delete', 'patch'],
        onComplete: function(swaggerApi, swaggerUi){
          if(typeof initOAuth == "function") {
            /*
            initOAuth({
              clientId: "your-client-id",
              realm: "your-realms",
              appName: "your-app-name"
            });
            */
          }

          $('pre code').each(function(i, e) {
            hljs.highlightBlock(e)
          });

          addApiKeyAuthorization();
        },
        onFailure: function(data) {
          log("Unable to Load SwaggerUI");
        },
        docExpansion: "none",
        sorter : "alpha"
      });

      function addApiKeyAuthorization(){
        var key = encodeURIComponent($('#input_apiKey')[0].value);
        if(key && key.trim() != "") {
            var apiKeyAuth = new SwaggerClient.ApiKeyAuthorization("api_key", key, "header");
            window.swaggerUi.api.clientAuthorizations.add("api_key", apiKeyAuth);
            log("added key " + key);
        }
      }

      $('#input_apiKey').change(addApiKeyAuthorization);

      // if you have an apiKey you would like to pre-populate on the page for demonstration purposes...

        var apiKey = "myApiKeyXXXX123456789";
        $('#input_apiKey').val(apiKey);


      window.swaggerUi.load();

      function log() {
        if ('console' in window) {
          console.log.apply(console, arguments);
        }
      }
  });
  </script>

and this is what I see in Chrome's tab when I click explore -

Remote Address:[::1]:9292
Request URL:http://localhost:9292/v1
Request Method:GET
Status Code:401 Unauthorized
Response Headers
view source
Access-Control-Allow-Credentials:true
Access-Control-Allow-Methods:GET, POST, OPTIONS, PUT, DELETE
Access-Control-Allow-Origin:null
Access-Control-Expose-Headers:
Access-Control-Max-Age:1728000
Connection:Keep-Alive
Content-Length:27
Content-Type:application/json
Date:Wed, 06 May 2015 10:59:46 GMT
Server:WEBrick/1.3.1 (Ruby/2.1.2/2014-05-08)
Vary:Origin
Request Headers
view source
accept:application/json;charset=utf-8,*/*
Accept-Encoding:gzip, deflate, sdch
Accept-Language:en-US,en;q=0.8
Cache-Control:no-cache
Connection:keep-alive
Host:localhost:9292
Origin:null
Pragma:no-cache
User-Agent:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2311.135 Safari/537.36

@ponelat
Copy link
Member

ponelat commented May 6, 2015

Are you trying to use an api_key to access your spec?
...I've been looking at executing operations (eg: GET /pet).

@jaman1020
Copy link
Author

I was...I just whitelisted the swagger url and everything loaded...doh
I did, however, get a Uncaught TypeError: Cannot read property 'undefined' of undefined error after it loaded. I think I remember seeing that in another issue? stacktrace if helpful -

Uncaught TypeError: Cannot read property 'undefined' of undefined
9.Operation.resolveModel    @   index.js:248
9.module.exports    @   index.js:131
(anonymous function)    @   spec-converter.js:38
arrayEach   @   binaryIndex.js:28
65.module.exports   @   mergeData.js:45
(anonymous function)    @   spec-converter.js:18
61.module.exports   @   isLaziable.js:13
baseForOwn  @   createFind.js:24
60.module.exports   @   isIndex.js:1
65.module.exports   @   mergeData.js:46
3.SwaggerClient.buildFromSpec   @   spec-converter.js:12
6.Resolver.resolve  @   model.js:135
(anonymous function)    @   resolver.js:218
7.SwaggerSpecConverter.finish   @   operation.js:401
7.SwaggerSpecConverter.resourceListing.http.on.response @   operation.js:275
(anonymous function)    @   spec-converter.js:508
111.Request.callback    @   index.js:24
(anonymous function)    @   index.js:24
112.Emitter.emit    @   index.js:24
111.Request.end.xhr.onreadystatechange  @   index.js:24

@ponelat
Copy link
Member

ponelat commented May 6, 2015

Sorry, I'm back (so is github)
Hmm, undefined of undefined - ain't that a pickle. I'm not familiar with the issue (probably is out there) but this looks like an unguarded variable reference.

Could be an error in the spec, that's causing this ugly error. Which isn't very friendly at all.
If you like I can take a look at the spec, otherwise... try validating it with swagger-tools. To get you going. This is an issue in the error reporting at the very least, but it may be related to the spec.

@webron
Copy link
Contributor

webron commented May 6, 2015

Otherwise, you can share your definition with us and we'll try to find the problem.

@ifig
Copy link

ifig commented May 21, 2015

Anything new concerning the missing headers?

@mrtristan
Copy link

think this is related?

domaindrivendev/Swashbuckle.WebApi#353

I'm changing my request type from json to xml and it's not returning an error and just kicking back those javascript errors in the chrome console.

don't mean to hijack but seems related so maybe this will help.

@webron
Copy link
Contributor

webron commented May 22, 2015

@mrtristan - completely unrelated.

@ponelat
Copy link
Member

ponelat commented May 22, 2015

hey @ifig, I don't think there is an actual issue with missing headers... but if you'd like to, you can show us your spec and we can see if anything sticks out.
@jaman1020 how goes your quest for API heaven?

@ifig
Copy link

ifig commented May 22, 2015

Well, I thought it was the same problem as described before : I want to request the url where my swagger specs are defined, but for that, I need to add a token in the header when I change the api key.
I added the following lines, but I can't see that header going in the request.

$('#input_apiKey').change(function() {
  var key = $('#input_apiKey')[0].value;
  if(key && key.trim() != "") {
    swaggerUi.api.clientAuthorizations.add("key", new SwaggerClient.ApiKeyAuthorization("api_key", key, "header"));
  }
})

@ponelat
Copy link
Member

ponelat commented May 22, 2015

@ifig if you're hiding the spec itself behind an auth layer, take a look at this comment...
#1171 (comment)
Does that helps clarify things?

@ifig
Copy link

ifig commented May 22, 2015

Well, I have no idea of what happened, but I forked again the UI from github and now I can see the headers passing through... That's really weird though. Another question but I shouldn't probably ask it in this thread : is there a way to pass a token in the headers just to access the documentation (that's what I do for now), and then pass a different token in the headers for each route I test?

@ponelat
Copy link
Member

ponelat commented May 22, 2015

Yup, I believe that's possible. It's not an area I'm familiar with... here is the spec reference .. https://github.com/swagger-api/swagger-spec/blob/master/versions/2.0.md#security-requirement-object

and you can put it on the operation level...
https://github.com/swagger-api/swagger-spec/blob/master/versions/2.0.md#operation-object

@ponelat
Copy link
Member

ponelat commented May 22, 2015

For future reference here is the Gist link I shared over IRC @ifig....
https://gist.github.com/ponelat/05c775d06397b24811a4

Allowing a custom callback function to alter the request object, pre-flight.

@jaman1020
Copy link
Author

@ponelat my issue was twofold -

  1. I was trying to send an API token in the header with the initial swagger doc load. I just whitelisted that URL instead and it worked.
  2. My Grape-swagger gem generates documentation for an older version of swagger and @webron was very helpful and let me know there were some issues with converting to 2.0. He gave me a link to an older version of swagger-UI and everything worked just fine.

Whenever grape swagger gets updated to swagger2.0 I'll switch to the current version of swagger UI

@webron
Copy link
Contributor

webron commented May 28, 2015

@jaman1020 - have we covered the topic?

@jaman1020
Copy link
Author

Yeah, from my standpoint I'm good now, although I'm not sure if this issue has evolved into a separate concern other people have?

@webron
Copy link
Contributor

webron commented Jun 3, 2015

What concern? Sorry, long thread.

@jaman1020
Copy link
Author

I hadn't looked too closely at it, but what @ifig and @mrtristan were referring to about their header troubles. Seemed to be slightly different than mine.

@webron
Copy link
Contributor

webron commented Jun 3, 2015

Well, I'll leave it to @ponelat - though technically, worst case, they can open separate issues if it's unrelated.

@ponelat
Copy link
Member

ponelat commented Jun 4, 2015

I believe the original issue (and some incidental) have been resolved? Closeable?
@ifig @jaman1020 @mrtristan @webron

@webron
Copy link
Contributor

webron commented Jun 4, 2015

Well, I'll close it due to lack of response from the other participants. Please open a new issue if needed.

@webron webron closed this as completed Jun 4, 2015
@samillm
Copy link

samillm commented Aug 4, 2015

Hi,

I'm having a similar problem I think that I've set up my swagger ui but when I check the headers they don't get sent. I have logs that tell me that the authentication keys get read in but never get sent in these request headers.

Here's the relevant code

function addApiKeyAuthorization(windowName){
      log("got key from " + windowName);

      var key = get('accessToken');
      if(key && key.trim() != "") {
          var apiKeyAuth = new SwaggerClient.ApiKeyAuthorization("api_key", key, "header");
          window.windowName.api.clientAuthorizations.add("api_key", apiKeyAuth);
          log("added key " + key + "from " + windowName);
      }
    }

Thanks!!

@ostretsov
Copy link

Hi! Same with @samillm problem. My js code is from repo.

@itai-codefresh
Copy link

@Rufog and @samillm are right.
the headers does appear in the curl string but they are not being sent in the request.
please point us to the place to fix this or fix it

@webron
Copy link
Contributor

webron commented Aug 17, 2015

I'd suggest opening a new issue. This one is old and there have been several versions released since.

denis-yuen added a commit to Consonance/consonance that referenced this issue Sep 25, 2015
This doesn't seem to work with the "Try it now" button in the GUI.
Maybe this is going on?
swagger-api/swagger-ui#1244
@nityanarayan44
Copy link

Hello all,
i have a new issue:::>

I am trying to add 'Access-Control-Allow-Origin' in header. to do so i added this line...
window.swaggerUi.api.clientAuthorizations.add("headerKey", apiKeyAuth);
window.swaggerUi.api.clientAuthorizations.add("headerKey", new SwaggerClient.ApiKeyAuthorization('Allow-Access-Control-Origin', '*', "header"));

but i m getting this when i explore the request header :::>

Accept:*/*
Accept-Encoding:gzip, deflate, sdch
Accept-Language:en-US,en;q=0.8
Access-Control-Request-Headers:accept, developer_key, access-control-allow-origin
Access-Control-Request-Method:GET
Connection:keep-alive

there is no extra custom header added in the request header. it is adding my access-control-allow-origin as a value into Access-Control-Request-Headers.

i want to add this access-control-allow-origin as a new custom header like .:::>

Accept:*/*
Accept-Encoding:gzip, deflate, sdch
Accept-Language:en-US,en;q=0.8
Access-Control-Request-Headers:accept, developer_key
Access-Control-Allow-Origin: *
Access-Control-Request-Method:GET
Connection:keep-alive

can any one suggest me, what am i doing wrong, or what should i do extra to do this .....

@webron
Copy link
Contributor

webron commented Mar 16, 2016

@nityanarayan44 if you have a new issue, it's better to open a new ticket. We can't track closed tickets.

@dazza-codes
Copy link

For those who land here, like me, looking for more information, the missing piece for me was the matching name for the securityDefinitions, security and the JS code use of the same name. For example, here is some swagger spec JSON to specify global API token access:

    "securityDefinitions": {
      "my_token": {
        "type": "apiKey",
        "description": "Authorization Token",
        "name": "my_token",
        "in": "header"
      }
    },
    "security": [
      { "my_token": [] }
    ],

Given that API spec, the JS code to match must use the same name, i.e. "my_token", as in:

var tokenAuth = new SwaggerClient.ApiKeyAuthorization("Authorization", "Token " + token, "header");
window.swaggerUi.api.clientAuthorizations.add("my_token", tokenAuth);

The name of the securityDefinitions is arbitrary and crucial. Most of the examples use "api_key", but you might want something else. The string "api_key" is just a name, it's not a reserved identifier with special meaning for swagger-ui, it's arbitrary (AFAICT).

@fehguy
Copy link
Contributor

fehguy commented Sep 8, 2016

@darrenleeweber thank you for sharing your findings, which are indeed correct based on the specification.

@ahallora
Copy link

ahallora commented Feb 6, 2017

@darrenleeweber a thumb up is not merely enough credit! THANK YOU!!!! ❤️ 😄

@firedock
Copy link

@darrenleeweber thanks!

@phye
Copy link

phye commented May 1, 2017

@darrenleeweber Thanks for this finding! Indeed solved my problem 👍

@svakhg
Copy link

svakhg commented Jan 15, 2018

I work on Laravel 5.4, so i just edit file index.blade.php like below it works. i use Authentication header with Bearer

function addApiKeyAuthorization() {
var key = $('#input_apiKey')[0].value;

            if (key && key.trim() != "") {
                var apiKeyAuth = new SwaggerClient.ApiKeyAuthorization("Authentication", key, "header");
                window.swaggerUi.api.clientAuthorizations.add("Bearer", apiKeyAuth);
            }
        }

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

No branches or pull requests