Adding Basic Authorization for Swagger-UI - basic-authentication

I have currently deployed a swagger project but I am having trouble adding some basic authorization to it. Currenty when you click on the "Try it out!" button you are required to log in to an account to access the results. I have an account that I want to automatically be used everytime someone tries to access the api. Bellow is my index.html for the project:
<!DOCTYPE html>
<html>
<head>
<title>Swagger UI</title>
<link href='css/screen.css' media='screen' rel='stylesheet' type='text/css'/>
<link href='css/screen.css' media='print' rel='stylesheet' type='text/css'/>
<script src='lib/jquery-1.8.3.js' type='text/javascript'></script>
<script src='lib/jquery.slideto.min.js' type='text/javascript'></script>
<script src='lib/jquery.wiggle.min.js' type='text/javascript'></script>
<script src='lib/jquery.ba-bbq.min.js' type='text/javascript'></script>
<script src='lib/handlebars-1.0.rc.1.js' type='text/javascript'></script>
<script src='lib/underscore-min.js' type='text/javascript'></script>
<script src='lib/backbone-min.js' type='text/javascript'></script>
<script src='lib/swagger.js' type='text/javascript'></script>
<script src='lib/swagger-ui.js' type='text/javascript'></script>
<script src='lib/highlight.7.3.pack.js' type='text/javascript'></script>
<script type="text/javascript">
$(function () {
window.swaggerUi = new SwaggerUi({
discoveryUrl:"https://localhost:8080/AssistAPI/api-docs.json",
apiKey:"",
dom_id:"swagger-ui-container",
supportHeaderParams: true,
supportedSubmitMethods: ['get', 'post', 'put'],
onComplete: function(swaggerApi, swaggerUi){
if(console) {
console.log("Loaded SwaggerUI")
console.log(swaggerApi);
console.log(swaggerUi);
}
$('pre code').each(function(i, e) {hljs.highlightBlock(e)});
},
onFailure: function(data) {
if(console) {
console.log("Unable to Load SwaggerUI");
console.log(data);
}
},
docExpansion: "none"
});
window.authorizations.add("key", new ApiKeyAuthorization("Authorization", "XXXX"header"));
//window.authorizations.add("key", new ApiKeyAuthorization("username", "rmanda", "header"));
window.swaggerUi.load();
});
</script>
</head>
<body class="swagger-section">
<div id='header'>
<div class="swagger-ui-wrap">
<a id="logo" href="http://swagger.io">swagger</a>
<form id='api_selector'>
<div class='input'><input placeholder="http://example.com/api" id="input_baseUrl" name="baseUrl" type="text"/></div>
<div class='input'><input placeholder="api_key" id="input_apiKey" name="apiKey" type="text"/></div>
<div class='input'><a id="explore" href="#">Explore</a></div>
</form>
</div>
</div>
<div id="message-bar" class="swagger-ui-wrap"> </div>
<div id="swagger-ui-container" class="swagger-ui-wrap"></div>
</body>
</html>
I am trying to determine where the information is supposed to go to allow Basic Authorization. I know it involved the following lines of code, but can someone please explain to me in a little more detail where things go exactly. I have come to the realization that the documentation for swagger on GitHub is not very clear or helpful
window.authorizations.add("key", new ApiKeyAuthorization("Authorization", "XXXX"header"));
window.authorizations.add("key", new ApiKeyAuthorization("username", "password", "header"));

Swagger UI 3.x
In Swagger UI 3.13.0+, you can use the preauthorizeBasic method to pre-fill the Basic auth username and password for "try it out" calls.
Assuming your API definition includes a security scheme for Basic auth:
swagger: '2.0'
...
securityDefinitions:
basicAuth:
type: basic
security:
- basicAuth: []
you can specify the default username and password for Basic auth like so:
// index.html
const ui = SwaggerUIBundle({
url: "https://my.api.com/swagger.yaml",
...
onComplete: function() {
// "basicAuth" is the key name of the security scheme in securityDefinitions
ui.preauthorizeBasic("basicAuth", "username", "password");
}
})
"Try it out" will use the specified username and password, and if you click the "Authorize" button in Swagger UI, you will see that the username and masked password are pre-filled in the UI.
This answer also contains a solution for Swagger UI 3.1.6—3.12.1, which do not have the preauthorizeBasic feature.

The correct setting for Basic authentication Header is:
Authorization: Basic username:password
The String username:password needs to be encoded using RFC2045-MIME a variant of Base64.
See more details here: https://en.wikipedia.org/wiki/Basic_access_authentication#Client_side
Then, to configure this header, you should do:
Considering that the Base64 encoding for username:password is dXNlcm5hbWU6cGFzc3dvcmQ=
swaggerUi.api.clientAuthorizations.add("key", new SwaggerClient.ApiKeyAuthorization("Authorization", "Basic dXNlcm5hbWU6cGFzc3dvcmQ=", "header"));
Read more about this here:
https://github.com/swagger-api/swagger-ui

I had a similar problem, the suggested answers are correct in my case I end up adding something in the index.html like:
var myAuth = "Basic " + btoa("user:password");
window.authorizations.add("key", neSwaggerClient.ApiKeyAuthorization("Authorization", myAuth, "header"));
I added this on either the marked method addApiKeyAuthorization or you can create another method but call it after the window.swaggerUi.load();
But if you have your swagger-ui running as "stand alone" with something like gulp or grunt you may require to configure the services to accept all OPTIONS request.
I struggle a little with that, I hope it helps someone.
Regards

you can add/change this function in your dist/index.html file
function addApiKeyAuthorization(){
var key = encodeURIComponent($('#input_apiKey')[0].value);
if(key && key.trim() != "") {
key = 'Basic '+key;
var apiKeyAuth = new SwaggerClient.ApiKeyAuthorization("Authorization", key, "header");
window.swaggerUi.api.clientAuthorizations.add("Authorization", apiKeyAuth);
log("added key " + key);
}
}
OR you can move on new version of Swagger 2.0 , this is known issue is was fixed.

Related

Cannot get user info with Google Identity Services

Well, I'm integrating the Google Identity Services into my application. But it doesn't run.
I'm following the instruction give in https://developers.google.com/identity/gsi/web
So I added these lines into the head of the index.html file
<meta name="google-signin-client_id" content="MY_GOOGLE_ID.apps.googleusercontent.com">
<script src="https://accounts.google.com/gsi/client" async defer></script>
and these at the beginning of the body:
<script>
function handleCredentialResponse(response) {
console.log('hello, world');
console.log("Encoded JWT ID token: " + response.credential);
}
window.onload = function () {
google.accounts.id.initialize({
client_id: 'MY_GOOGLE_ID.apps.googleusercontent.com',
callback: handleCredentialResponse
});
// Display the One Tap prompt
google.accounts.id.prompt();
// Display the Sign In With Google Button
google.accounts.id.renderButton(
document.getElementById("buttonDiv"),
{ theme: 'outline', size: 'large' }
);
}
</script>
Then added this line into my Navbar.js
<li className='nav-item'>
<div id="buttonDiv" class="g-signin2" data-onsuccess="onSignIn"></div>
</li>
As far as I understood, when the user correctly sign-in, the handleCredentialResponse callback should be called by Google, but nothing appeared on my console.log.
I can login correctly, using different credentials. The user image and email address appear into the button, but I'm not notified of the event.
I tried to follow the instruction, but seems that Google suggest these new approach referred in the link at the top, but the instruction still are for the old implementation.
Can anyone help, please?
So when you initialise the button in your tag, it will have a "data-callback" parameter. Pass your handler in that like below.
<html>
<body>
<script src="https://accounts.google.com/gsi/client" async defer></script>
<div id="g_id_onload"
data-client_id="YOUR_GOOGLE_CLIENT_ID"
**data-callback="handleCredentialResponse"**
data-login_uri="https://your.domain/your_login_endpoint"
data-auto_prompt="false">
</div>
<div class="g_id_signin"
data-type="standard"
data-size="large"
data-theme="outline"
data-text="sign_in_with"
data-shape="rectangular"
data-logo_alignment="left">
</div>
</body>
</html>

AngularFire doesn't show data from Firebase Database

I'm following this video. But I have trouble implementing it. This is the HTML file.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Welcome to Firebase Hosting</title>
<!-- AngularJS -->
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.8/angular.min.js"></script>
<!-- AngularFire -->
<script src="https://cdn.firebase.com/libs/angularfire/2.0.2/angularfire.min.js"></script>
<!-- Firebase -->
<script src="https://www.gstatic.com/firebasejs/3.3.0/firebase.js"></script>
<script src="app.js"></script>
</head>
<body ng-app="app">
<div id="message" ng-controller="MyController as ctrl">
<pre>
{{ ctrl.object | json }}
</pre>
</div>
</body>
</html>
And my app.js file is this.
(function(){
// Initialize Firebase
var config = {
apiKey: "SOME KEY",
authDomain: "tier2list.firebaseapp.com",
databaseURL: "https://tier2list.firebaseio.com",
storageBucket: "",
};
firebase.initializeApp(config);
angular.module('app', ['firebase']).controller('MyController', function($firebaseObject){
const rootRef = firebase.database().ref().child('tier2list');
const ref = rootRef.child('object');
this.object = $firebaseObject(ref);
});
}());
This is my database structure.
But the result is as follows.
And there is no errors in the console as well. Database rules are as follows.
{
"rules": {
".read": true,
".write": true
}
}
The problem is in the path you synchronize:
const rootRef = firebase.database().ref().child('tier2list');
There is no child tier2list in your database, so you will get an empty object.
Instead, you're trying to synchronize the entire database, which you can do by:
const rootRef = firebase.database().ref()
I was in the middle of this when Frank answered. He has the right answer, but here is what your database should look like in order to work with David's code:
In his walk through, he is already inside of the angular node, so that could be a little confusing.
I also created a Github repo for the project in case anyone is having trouble making it for themselves:
https://github.com/LukeSchlangen/angularFireQuickDemo

angularjs and brackets live preview: The simplest code doesn't work

I'm a newbie to angularJS and I'm trying to make the simple thing to work but I fail.
HTML:
<!DOCTYPE html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.9/angular.min.js"></script>
<script src="main.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css">
<link rel="stylesheet" href="main.css">
</head>
<body ng-app="app" ng-strict-di>
<div class="test" ng-controller="testSrc">
<p> {{ blah }} </p>
<img ng-src="{{ URLImage }}"/>
<button class="btn btn-sucess" ng-click="goYahoo()">Yahoo</button>
<button class="btn btn-sucess" ng-click="goGoogle()">Google</button>
</div>
</body>
</html>
JS:
var app = angular.module("app", []);
app.controller('testSrc', ['$scope,$location', function ($scope, $location) {
"use strict";
$scope.blah = "blah blah";
$scope.URLImage = 'https://upload.wikimedia.org/wikipedia/commons/thumb/5/53/Google_%22G%22_Logo.svg/512px-Google_%22G%22_Logo.svg.png';
$scope.goGoogle = function () { $location.url('localhost:58164/g'); };
$scope.goYahoo = function () { $location.url('localhost:58164/y'); };
}]);
app.config(function ($routeProvider) {
"use strict";
$routeProvider
.when('/', {
templateUrl : 'index.html'
})
.when('/g', {
templateUrl : 'http://www.google.com'
})
.when('/y', {
templateUrl : 'http://www.yahoo.com'
});
});
The code has passed all lint warnings. I use the live preview of brackets that opens up Internet explorer. I encounter 3 issues:
1) {{ blah }} does not translate into blah blah, I see {{ blah }} as if the js is ignored. same for the ng-src of the img. It is ignored and I don't see the image.
2) the 2 buttons are not colored in green as I expect it to be from the bootstrap css. I tried it in jsFiddle and did see them as green but when I tried again now, they were regular, not sure what did I do wrong.
3) Routing: I want to browse to Google/Yahoo when navigating to specific url g and y using the 2 buttons. When I open the live preview, the url is: http://127.0.0.1:58164/index.html so how can I route this correctly? http://127.0.0.1:58164/index.html/g won't work.
I'm kinda lost here, not sure if the problem is my code, the browser of the live preview though the JS didn't work also in jsFiddle...
1) You're injecting the dependencies into your controller incorrectly - you need a string for each argument of the function. It's an easy mistake to make!
app.controller('testSrc', ['$scope,$location', function ($scope, $location) { // Wrong
app.controller('testSrc', ['$scope', '$location', function ($scope, $location) { // Right
2) You've misspelled the class name in your buttons. 'sucess' should be 'success'.
<button class="btn btn-sucess" ng-click="goYahoo()">Yahoo</button>
^^^^^^
3) There's numerous things wrong with your routing:
You haven't included the ngRoute module in your HTML - it hasn't been included in the base Angular package for a long time now.
Once that's done, you need to add it as a dependency: var app = angular.module("app", ["ngRoute"]); and add an ng-view tag to your HTML.
By default, the router will use 'hashbangs' for the URL - so the URL would be something along the lines of `http://127.0.0.1:58164/index.html#/g. If this isn't acceptable for you, I'd look into HTML5 mode.
All that being said, I don't think ngRoute will help you accomplish what you're trying to do. The router is designed to route through the pages of your app, not to external sites, so trying to load HTML from another domain probably won't work.
I'd recommend running through the official Angular tutorial if you haven't already - it covers all this stuff quite well. I'd also recommend Shaping Up With Angular.js on Code School, if you would prefer something a bit more hands-on.

getting error 400 on signing with google

I want to create google login in my website and code used is from google developer website here and I am using php for coding and my code is
<!DOCTYPE html>
<html>
<head>
<title>Google Login</title>
<meta name="google-signin-client_id" content="9252517****-o9350mh2vrp58maddlv0aeitkd0c****.apps.googleusercontent.com">
<script src="https://apis.google.com/js/platform.js" async defer></script>
<script>
function onSignIn(googleUser)
{
var profile = googleUser.getBasicProfile();
console.log('ID: ' + profile.getId()); // Do not send to your backend! Use an ID token instead.
console.log('Name: ' + profile.getName());
console.log('Image URL: ' + profile.getImageUrl());
console.log('Email: ' + profile.getEmail());
}
function signOut()
{
var auth2 = gapi.auth2.getAuthInstance();
auth2.signOut().then(function ()
{
console.log('User signed out.');
});
}
</script>
</head>
<body>
<div align="center" margin-top="100px">
<div class="g-signin2" data-onsuccess="onSignIn"></div>
Sign out
</div>
</body>
</html>
After signin I am getting error like this Error: redirect_uri_mismatch
The JavaScript origin in the request: http://localhost did not match a registered JavaScript origin.
You can check error here.
Please help me to get out of this problem.
After long search I found solution which magically solve my problem.
As shown in error http://localhost did not match a registered JavaScript origin I set http://localhost instead of full path in my redirect url in console.developer site and it works.

Basic angularjs code not working properly

Have installed the angularjs and Twitter.Bootstrap packages succesfully
This is my index.html:
<!DOCTYPE html>
<html ng-app="TodoApp" xmlns="http://www.w3.org/1999/xhtml">
<head>
<script src="Scripts/jquery-1.9.1.js"></script>
<script src="Scripts/bootstrap.js"></script>
<script src="Scripts/angular.js"></script>
<script src="Scripts/angular-resource.js"></script>
<script src="Scripts/app.js"></script>
<link rel="stylesheet" type="text/css" href="Content/bootstrap.css" />
<title>Amazing Todo</title>
</head>
<body>
<div class="container">
<div ng-view></div>
</div>
</body>
</html>
This is my app.js:
var TodoApp = angular.module("TodoApp", []).
config(function ($routeProvider) {
$routeProvider.
when('/', { controller: ListCtrl, templateUrl: 'list.html' }).
otherwise({ redirectTo: '/' });
});
var ListCtrl = function ($scope, $location) {
$scope.test = "testing";
};
And, this is my list.html:
<h1>Test: {{test}}</h1>
This should work fine. However the index.html is not showing the content of list.html. I think the angularjs part is not working properly.
No idea about what am i doing wrong?
Once you have defined a module, you need to define your controllers for that module and not independently.
Thus, your controller should be rewritten as:
TodoApp.controller('ListCtrl', [ '$scope', '$location',
function ($scope, $location) {
$scope.test = "Testing";
}
]);
This should show the view in question.
I would say, that if you check errors in console (in Chrome or IE press F12) you should see:
...Failed to instantiate module TodoApp due to:
Error: [$injector:unpr] Unknown provider: $routeProvider...
The reason for this expectation is that we ask IoC to inject $routeProvider while not correctly listing dependent modules. This is the above code:
var TodoApp = angular
// here we say: we do not need any other module
.module("TodoApp", [])
// here we ask: inject $routeProvider from other module
.config(function ($routeProvider)
So to make it runing we have to include the module 'ngRoute'
var TodoApp = angular
// here we say: we need these modules to make our module working properly
.module("TodoApp", [
'ngRoute'
])
// now we can ask for the provider,
// using minification-safe syntax
.config(
[ '$routeProvider',
function ($routeProvider) {
$routeProvider.
...
}]);
And also do not forget to also reference this module scripts:
<script src="Scripts/angular.js"></script>
<script src="Scripts/angular-resource.js"></script>
<!-- here we have to load this module -->
<script src="Scripts/angular-route.js"></script>
What is your directory structure can you check if list.html is in the same directory as index.html, if not specify a relative path from the application root?
Since no one has posted a full correct answer to this question and it hasn't been closed yet, here is another answer.
This is your function:
var ListCtrl = function ($scope, $location) {
$scope.test = "testing";
};
This is a bare function, which isn't of much use. You need a controller so that Angular knows what to do with {{ test }}:
<div ng-controller="someController">
<h1>{{ test }}</h1>
</div>
If you insist on keeping the function as a separate variable, you could do so and still have a controller:
var ListCtrl = function ($scope, $location) {
$scope.test = "testing";
};
TodoApp.controller('someController', ListCtrl);
This also works.
Despite of this, your UI won't show, as there's an error in it:
var TodoApp = angular.module("TodoApp", [])
You're using $routeProvider and .when(),.otherwise(), for which you need ngRoute as a dependency:
var TodoApp = angular.module("TodoApp", ['ngRoute'])
Your app should work after that.

Resources