The endpoint where my swagger.json
file (localhost:8000/rest/swagger.json
) requires an AuthType
header to access it. How can I get Swagger UI to add this when it makes its initial request for the swagger.json
file?
What I've tried so far:
$(function () {
var token = 'xxx';
window.swaggerUi = new SwaggerUi({
url: "http://" + location.host + "/rest/swagger.json",
dom_id: "swagger-ui-container",
supportedSubmitMethods: ['get', 'post', 'put', 'delete', 'patch'],
onComplete: function (swaggerApi, swaggerUi) {
var apiKeyAuth = new SwaggerClient.ApiKeyAuthorization("AuthToken", token, "header");
window.swaggerUi.api.clientAuthorizations.add("AuthToken", apiKeyAuth);
$('pre code').each(function (i, e) {
hljs.highlightBlock(e)
});
},
docExpansion: "none",
apisSorter: "alpha",
showRequestHeaders: false
});
swaggerUi.load();
});
But when I open Chrome Dev Tools and look at what request was made to localhost:8000/rest/swagger.json
it has no AuthType
header and has a 401 Unauthorized
response.
Note: It doesn't seem like the onComplete
function ever gets called (i'm guessing it requests swagger.json
before that would usually get called so it falls into the onFailure
block instead when the request fails)
The endpoint where my swagger.json
file (localhost:8000/rest/swagger.json
) requires an AuthType
header to access it. How can I get Swagger UI to add this when it makes its initial request for the swagger.json
file?
What I've tried so far:
$(function () {
var token = 'xxx';
window.swaggerUi = new SwaggerUi({
url: "http://" + location.host + "/rest/swagger.json",
dom_id: "swagger-ui-container",
supportedSubmitMethods: ['get', 'post', 'put', 'delete', 'patch'],
onComplete: function (swaggerApi, swaggerUi) {
var apiKeyAuth = new SwaggerClient.ApiKeyAuthorization("AuthToken", token, "header");
window.swaggerUi.api.clientAuthorizations.add("AuthToken", apiKeyAuth);
$('pre code').each(function (i, e) {
hljs.highlightBlock(e)
});
},
docExpansion: "none",
apisSorter: "alpha",
showRequestHeaders: false
});
swaggerUi.load();
});
But when I open Chrome Dev Tools and look at what request was made to localhost:8000/rest/swagger.json
it has no AuthType
header and has a 401 Unauthorized
response.
Note: It doesn't seem like the onComplete
function ever gets called (i'm guessing it requests swagger.json
before that would usually get called so it falls into the onFailure
block instead when the request fails)
2 Answers
Reset to default 3I will provide you my scenario. To be very honest the READ-ME of swagger is not upto the mark(that is my view) . They have not mentioned anything about adding a header to the url request.
My use case was that i had to call my API to get JSON response.(My API was protected by login_required decorator , which requires xcsrf-token to be sent in the header )
In your case, yours localhost:8000/rest/swagger.json is analogous to my API.
How to approach this problem?
- When we SwaggerUIBundle.A key named "spec" ( will explain spec later in the snippet) has to be mapped with JSON response value . This JSON response provides initial structure for swagger-ui page .
What are you saying ? What kind of UI are you talking about ? What is the structure of JSON Response ?
Click here for Swagger-UI example
To make page of this type using swagger-ui you need to supply it with JSON reponse
Click here for JSON reponse that you need to generate either using APIs or in your case ocalhost:8000/rest/swagger.json
Use AJAX request to make a call to your API or localhost:8000/rest/swagger.json.
Now in your success call, JSON has to be equated to "spec".
Explanation Using Code Snippets
- Instantiate SwaggerUIBundle object. Notice spec key which has to be mapped to JSON response value. dom_id can be ID of any div.
const ui = SwaggerUIBundle({
spec: {},// put JSON response here.
dom_id: '#swagger-ui',
presets: [
SwaggerUIBundle.presets.apis,
// yay ES6 modules ↘
Array.isArray(SwaggerUIStandalonePreset) ? SwaggerUIStandalonePreset : SwaggerUIStandalonePreset.default
],
plugins: [
SwaggerUIBundle.plugins.DownloadUrl
],
layout: "StandaloneLayout"
})
window.ui = ui
- Now enclose this object instantiation, in a function .
window.foo = function(spec){
const ui = SwaggerUIBundle({
spec: spec,
dom_id: '#swagger-ui',
presets: [
SwaggerUIBundle.presets.apis,
// yay ES6 modules ↘
Array.isArray(SwaggerUIStandalonePreset) ? SwaggerUIStandalonePreset : SwaggerUIStandalonePreset.default
],
plugins: [
SwaggerUIBundle.plugins.DownloadUrl
],
layout: "StandaloneLayout"
})
window.ui = ui
}
- Let us see how we can use ajax calls to call this function. We can add any token during this AJAX call.
window.onload = function() {
function apiCall(uri, data, methodType) {
const csrftoken = getCookie('csrftoken');
//Add header to the URL .
$.ajaxSetup({
beforeSend: function(xhr, settings) {
if (!this.crossDomain) {
xhr.setRequestHeader('X-CSRFToken', csrftoken);
}
}
});
$.ajax({
url: uri,
method: methodType,
contentType: 'application/json',
data: data,
success: function (response) {
var script = document.createElement('script');
// Calling the function which instantiates swaggerbundle object
foo(response)
},
error: function (error) {
}
});
}
// You can write your own getCookie function .
function getCookie(name) {
let cookieValue = null;
if (document.cookie && document.cookie !== '') {
let cookies = document.cookie.split(';');
for (let i = 0; i < cookies.length; i++) {
let cookie = jQuery.trim(cookies[i]);
// Does this cookie string begin with the name we want?
if (cookie.substring(0, name.length + 1) === (name + '=')) {
cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
break;
}
}
}
return cookieValue;
}
//['GET','POST']
apiCall('http://localhost:8000/rest/swagger.json',{},'GET');
}
- Here is the final snippet .
window.foo = function(spec){
const ui = SwaggerUIBundle({
spec: spec,
dom_id: '#swagger-ui',
presets: [
SwaggerUIBundle.presets.apis,
// yay ES6 modules ↘
Array.isArray(SwaggerUIStandalonePreset) ? SwaggerUIStandalonePreset : SwaggerUIStandalonePreset.default
],
plugins: [
SwaggerUIBundle.plugins.DownloadUrl
],
layout: "StandaloneLayout"
})
window.ui = ui
}
window.onload = function() {
function apiCall(uri, data, methodType) {
const csrftoken = getCookie('csrftoken');
//Add header to the URL .
$.ajaxSetup({
beforeSend: function(xhr, settings) {
if (!this.crossDomain) {
xhr.setRequestHeader('X-CSRFToken', csrftoken);
}
}
});
$.ajax({
url: uri,
method: methodType,
contentType: 'application/json',
data: data,
success: function (response) {
var script = document.createElement('script');
// Calling the function which instantiates swaggerbundle object
foo(response)
},
error: function (error) {
}
});
}
// You can write your own getCookie function .
function getCookie(name) {
let cookieValue = null;
if (document.cookie && document.cookie !== '') {
let cookies = document.cookie.split(';');
for (let i = 0; i < cookies.length; i++) {
let cookie = jQuery.trim(cookies[i]);
// Does this cookie string begin with the name we want?
if (cookie.substring(0, name.length + 1) === (name + '=')) {
cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
break;
}
}
}
return cookieValue;
}
//['GET','POST']
apiCall('http://localhost:8000/rest/swagger.json',{},'GET');
}
In your example you have window.swaggerUi
, but have not yet assigned the swaggerApi
variable to the window
object.
Try:
onComplete: function (swaggerApi, swaggerUi) {
window.swaggerApi = swaggerApi;
var apiKeyAuth = new SwaggerClient.ApiKeyAuthorization("AuthToken", token, "header");
window.swaggerUi.api.clientAuthorizations.add("AuthToken", apiKeyAuth);
$('pre code').each(function (i, e) {
hljs.highlightBlock(e)
});
}
Second:
While the browser may be able to figure the correct swaggerUi
variable try for the load:
window.swaggerUi.load();
Instead of:
swaggerUi.load();