-
-
Notifications
You must be signed in to change notification settings - Fork 394
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
On reloading Swagger UI, it is loosing the authentication #120
Comments
As far as Swagger UI allows via configuration is only setting the client id and client secret as well as some others, but not a username, password, or access token. https://github.com/swagger-api/swagger-ui/blob/master/docs/usage/oauth2.md Adding this to the javascript of resources/vendor/l5-swagger/index.blade.php will pass in the ID and secret. So it saves some typing.
The auth props component itself allows a username to be set, but not the password: https://github.com/swagger-api/swagger-ui/blob/master/src/core/components/auth/oauth2.jsx However it just calls authorizeOauth2 which you can access via: ui.authActions.authorizeOauth2()... After some hunting around there is:
Running this closes the "Authorize" lock so a valid token needs to be set. Considering there are a lot of ways to authorize it might be a headache to implement. We also need to intercept the response for when the authorization is provided, so additional Overall Swagger UI does not store tokens, and probably on purpose. There is no switch to enable this, but looks like there are little things that can be done to remember a token via cookie, local storage, indexdb, etc and when the page is reloaded, populate the token back in. |
So here is an example of remembering the token for OAuth2 password authentication (depends on Laravel Passport). This would go inside window.onload = function() {
var urlToDocs = @json($urlToDocs);
var passwordClient = @json(\Laravel\Passport\Client::where('password_client', 1)->whereNull('user_id')->first());
// Build a system
const ui = SwaggerUIBundle({
dom_id: '#swagger-ui',
url: urlToDocs,
operationsSorter: {!! isset($operationsSorter) ? '"' . $operationsSorter . '"' : 'null' !!},
configUrl: {!! isset($additionalConfigUrl) ? '"' . $additionalConfigUrl . '"' : 'null' !!},
validatorUrl: {!! isset($validatorUrl) ? '"' . $validatorUrl . '"' : 'null' !!},
oauth2RedirectUrl: "{{ route('l5-swagger.oauth2_callback') }}",
requestInterceptor: function(request) {
request.headers['X-CSRF-TOKEN'] = @json(csrf_token());
return request;
},
responseInterceptor: function (response) {
if (response.status >= 200 && response.status < 300) {
var docsUrl = @json(config('l5-swagger.paths.docs_json'));
var storageKeys = Object.keys(window.localStorage);
if (response.url.indexOf(urlToDocs) < 0 && storageKeys.indexOf('token') < 0 && response.obj) {
window.localStorage.setItem('token', JSON.stringify(response.obj));
}
}
return response;
},
presets: [
SwaggerUIBundle.presets.apis,
SwaggerUIStandalonePreset
],
plugins: [
SwaggerUIBundle.plugins.DownloadUrl
],
layout: "StandaloneLayout"
});
if (passwordClient) {
ui.initOAuth({
clientId: passwordClient.id,
clientSecret: passwordClient.secret,
});
}
var tokenData = window.localStorage.getItem('token');
var token = null;
if (tokenData) {
try {
token = JSON.parse(tokenData);
} catch(e) {
}
}
if (token) {
ui.authActions.preAuthorizeImplicit({
auth: {
schema: {
flow: 'password',
get: function (key) {
return this[key];
}
},
name: 'passport'
},
token: token,
isValid: true
});
}
window.ui = ui
} There is still the issue of if you log out, or reauthorize none of the token data is updated. Maybe there is a hook in Swagger UI for logging up / refreshing tokens. |
Thanks @joseph-montanez for this code ! The secret is (nowadays, on Laravel 5.6) hidden by default from the JSON view. You could get it by completing the third line with var passwordClient = @json(\Laravel\Passport\Client::where('password_client', 1)->whereNull('user_id')->first()->makeVisible('secret')); But be sure to know what you're doing :) And by the way, add this somewhere to keep the information that the user has logged out on refresh : var oldLogout = ui.authActions.logout;
ui.authActions.logout = function(payload) {
window.localStorage.removeItem('token');
return oldLogout(payload);
}; |
This is my solution for Bearer authKey in header: (function() {
const TOKEN_NAME = 'JwtToken';
setTimeout(function() {
// 1. If token already exists, set it from sessionStorage
const JWTToken = sessionStorage.getItem(TOKEN_NAME);
if (JWTToken) {
ui.authActions.preAuthorizeImplicit({
auth: {
schema: {
type: 'apiKey',
in: 'header',
name: 'Authorication',
get: function(key) {
return this[key];
},
},
name: 'bearer',
value: JWTToken,
},
token: {},
isValid: true,
});
}
// 2. If token was not set yet, save it to sessionStorage
const openBtn = document.querySelector('btn authorize unlocked');
if (openBtn) {
openBtn.addEventListener('click', function() {
setTimeout(function() {
const authBtn = document.querySelector('btn modal-btn auth authorize button');
authBtn.addEventListener('click', function(e) {
const tokenInput = document.querySelector('input:not([class])');
if (tokenInput && tokenInput.value) {
sessionStorage.setItem(TOKEN_NAME, tokenInput.value);
console.log('Token vas successfully saved!!!');
}
});
}, 1000);
});
}
}, 1000);
})(); |
hi @RAZWANN, can you post your answer here? answer was not working by the way, |
This is my solution:
|
Adding a listener to the authorize button did not work for me, so I came up with this solution: (function () {
const API_KEY = 'ApiKey';
setTimeout(function () {
// store the api key in the local storage
var originalAuthorize = ui.authActions.authorize;
ui.authActions.authorize = function (payload) {
window.localStorage.setItem(API_KEY, payload.ApiKeyScheme.value);
return originalAuthorize(payload);
};
// if logout is clicked delete the api key in the local storage
var originalLogout = ui.authActions.logout;
ui.authActions.logout = function (payload) {
window.localStorage.removeItem(API_KEY);
return originalLogout(payload);
};
// If token already exists, load it from local storage
const apiKey = window.localStorage.getItem(API_KEY);
if (apiKey) {
window.ui.preauthorizeApiKey('ApiKeyScheme', apiKey);
}
}, 1000);
})(); Note, depending on your security settings, you will get different data in the payload of the authorize function. Also the preAuthorize must match your security settings. |
Just putting "persistAuthorization: true" to SwaggerUIBundle json solved my problem.
You can find other needed parameters here. |
Closing due to no activity for a very long time |
On reloading Swagger UI, it is loosing the authentication.
@DarkaOnLine Is there a way to keep the user login even if I reload the Swagger UI?
Want to back this issue? Post a bounty on it! We accept bounties via Bountysource.
The text was updated successfully, but these errors were encountered: