http basic authorization with Flask REST - javascript

I am developing a simple REST service in flask.
I have been trying to implement basic authorization.
Whilst, I can pass the username and password from the webpage using manual entry, I can't seem to read them from the header.
Here is my code:
On the server
def test():
if request.authorization and request.authorization.username == '***' and request.authorization.password == '***':
return "Authorized"
else:
return make_response('Authorization failed', 401, {'WWW-Authenticate': 'Basic realm ="Login Required"'})
On the client - using JavaScript
<script>
$(document).ready(function(){
$("#authButton").click(function(){
$.ajax({
xhrFields: {
withCredentials: true
},
headers: {
'Authorization': "Basic " + btoa("***:***")
},
url: "********:5001/",
type: 'GET',
success: function(){
console.log("success");
},
error: function (){
console.log("error");
},
});
});
});
</script
>
I have also tried the Javascript code without the xhr fields section, but for neither do I get anything returned at all.
If I don't send the headers from the client it works and simply asks for manual input of the username and password.
All I'm trying to do is authenticate from the header.
Any pointers would be very gratefully received.

Related

Create a gist using GitHub API

I wanna create a gist using GitHub API. I tried an POST ajax request:
var gist = {
"description": "Avatars",
"public": true,
"files": {
"check.txt": {
"content": "Avatars list..."
}
}
};
$.ajax({
url: 'https://api.github.com/gists',
type: 'POST',
dataType: 'json',
data: JSON.stringify(gist),
success: function(e) {
console.log(e);
},
error: function(e) {
console.error("Error!: ", e);
}
});
But I always get the following error:
jquery-3.1.1.min.js:4 POST https://api.github.com/gists 401 (Unauthorized)
Can anyone help me?
Thanks
When you want to edit things on Github, you need to authorize your request. Either by adding a username and password to the request or an oauth token.
More information can be found in the authorization documentation: https://developer.github.com/v3/auth/
Since I ran across the same problem recently, let me add the examples requested by T.Todua
If you want to authenticate with username and password, add the following lines to your $.ajax request:
crossDomain: true,
beforeSend: function (XHR) {
XHR.setRequestHeader(
'Authorization','Basic ' + btoa(Username + ':' + Password)
);
},
If, however, you created an access token for your gists (see Github help and don't forget to check the "Gist" permission!) then add the following lines instead
crossDomain: true,
headers: {
'Authorization':'bearer ' + GitHubAccessToken
},
The GitHubAccessToken will be shown once (and only once!) immediately after creation, so make sure to store it in a safe location as everybody knowing this access token will be able to modify your gists (until you revoke it again).

protractor executeScript doesnot run the function

Im trying to post a api using for my registration page and i have used $HTTP request to post data
it('login page to patient dashboard with existing email and password', function() {
console.log('entering login page')
browser.get('http://localhost:9000/login.html');
browser.executeScript(function(callback) {
var $http;
$http = angular.injector(["ng"]).get("$http");
console.log('http request')
return $http({
url: "http://int.eclinic247.com/reg/create-patient",
method: "post",
data: {"firstName":"jya","lastName":"raq"},
dataType: "json"
}).success(function() {
return callback([true]);
console.log('done')
}).error(function(data, status) {
return callback([false, data, status]);
console.log('oops not done!!!!')
});
})
element(by.model(Objects.locators.passwordBox)).sendKeys(Objects.login.password);
I see that the executeScript block doesnot run and there are no errors too...and the test case passes
Is this the way to post a http request using protractor...Please suggest me the proper to post a data to back-end directly
Any help is much appreciated...Thanks in advance

couchDB 401 error

I have a couchDB database called "guestbook". I first used the code below to add the a user to the "_users" database:
$scope.submit = function(){
var url = "https://sub.iriscouch.com/_users/org.couchdb.user:" + $scope.name;
console.log(url);
$http({
url: url,
method: "PUT",
data: {name : $scope.name,
password: $scope.pass,
roles: [],
type: "user"
},
withCredentials: true,
headers: {"Authorization": auth_hash(adminUsername, adminPass)}
})
.success(function(data, status, headers, config){
console.log(headers);
console.log(config);
});
}
Once the user was added to _users I used Futon to add that user as member to my "guestbook" _security document.
After that I tried to used that username and password (that was added as a member to "guestbook" _security) to get all the documents in the "guestbook" database. See code below:
$scope.login = function(){
var url = "https://sub.iriscouch.com/guestbook/_all_docs";
$http({
url: url,
method: 'GET',
params: {
include_docs: true,
},
withCredentials: true,
headers: {"Authorization": auth_hash($scope.uname, $scope.upass)}
})
.success(function(data, status, headers, config){
$scope.book = data.rows;
console.log($scope.book);
});
}
function auth_hash(username, password)
{
return "Basic" +btoa(username + ":" + password);
}
But everytime I tired access the "_all_docs" I get a 401 unauthorised error. The username I am using to access has been added as a member into the _security documents of the guestbook database.
Can anyone help. What am I doing wrong.
Do you have added the user name w/o the org.couchdb.user prefix to the _security object?
I can easily understand your code but didn't see a obviously mistake. I would recommend you test your API calls with Postman (Chrome App) or similar to know whether the problem is client- or server-side caused.
401 indicates Couch is unable to log in your user rather than it's not allowing them access to the database.
Might be a copy/paste error in writing the code example, but it looks like your line:
return "Basic" +btoa(username + ":" + password);
Is missing a space between Basic and your hash in the returned string:
return "Basic " +btoa(username + ":" + password);
This will mean that your Authorization header isn't correct.
However, your first code block appears to use the same function successfully, so I'm clutching at straws.

jQuery.ajax to $http

I used this function
jQuery.ajax({
type: 'POST',
url: urlSubmit,
timeout: 5000,
dataType: 'text',
data: {
date : dataDate,
url : dataUrl,
domaine : dataDomaine,
email : dataEmail,
destinataire : dataDestinataire,
msg : dataMsg
},
"success": function (jqXHR, textStatus, errorThrown) {
console.log("AJAX success :) - statut " + textStatus);
$timeout(successMailZR_alerte, 3000);
},
"error": function (jqXHR, textStatus, errorThrown) {
console.log("AJAX fail :/ - statut " + textStatus);
$timeout(errorMailZR_alerte, 3000);
}
});
Whats the code is doing : code POST to a php script who send an email.
but, since i rewrited my code in a complete angularjs app, i do it like this :
$http({
method: 'POST',
url: urlSubmit,
timeout: 5000,
cache: false,
data: {
date : dataDate,
url : dataUrl,
domaine : dataDomaine,
email : dataEmail,
destinataire : dataDestinataire,
msg : dataMsg
},
headers: {'Content-Type': 'application/x-www-form-urlencoded'},
responseType: 'text',
}).
success(function(data, status, headers, config) {
console.log("AJAX success :) - statut " + status);
$timeout(successMailZR_alerte, 3000);
}).
error(function(data, status, headers, config) {
console.log("AJAX fail :/ - statut " + status);
$timeout(errorMailZR_alerte, 3000);
});
Problem is : with $http, i have a success 200 but nothing is posted and i have no return in my email. What's the problem ?
The problem is that jQuery's POST does send your data as form data (e.g. key-value pairs) (https://developer.mozilla.org/en-US/docs/Web/Guide/HTML/Forms/Sending_and_retrieving_form_data) whereas AngularJS sends your data in the request payload. For a difference between the two see the following SO question: What's the difference between "Request Payload" vs "Form Data" as seen in Chrome dev tools Network tab
In order to make your angular script works with your server you have to convert your data to a URL encoded string as described here: How can I post data as form data instead of a request payload?. Simply setting headers: {'Content-Type': 'application/x-www-form-urlencoded'} is not enough.
A different approach would be to adapt the back-end of your application to parse the message payload instead of the form data parameters.
To understand this one need to understand the request headers set by angular and jquery, There are differences with the headers like when request is post by jQuery then header might look like this:
POST /some-path HTTP/1.1
Content-Type: application/x-www-form-urlencoded // default header set by jQuery
foo=bar&name=John
You can see this in form data in the request made in the browser, if you use chrome then you can see this in chrome inspector at network tab, if you click the request then you can see the form data and content headers set by the jQuery.
On the other side with angular js $http service, when a request is made then you can find these:
POST /some-path HTTP/1.1
Content-Type: application/json // default header set by angular
{ "foo" : "bar", "name" : "John" }
The real difference is this you have a request payload not usual form data which is used by jQuery. so you need to do something extra at the server side like below.
Use this:
$data = json_decode(file_get_contents("php://input"));
echo $data->date;
// and all other params you have sent
This is due to its default headers
Accept: application/json, text/plain, * / *
Content-Type: application/json
and jQuery unlikely have something else:
Content-Type: application/x-www-form-urlencoded; charset=UTF-8

How to avoid pop up login when calling WCF service from jquery ajax

Friends,
I know you have been facing these kind of question a lot.I was unable to find an answer even after a lot of google search.Well, lets come to the issue.
Requirement: Call a WCF Service GET API with basic authentication enabled using jquery ajax request.
Client side code:
<script src="Scripts/jquery-1.9.1.min.js" type="text/javascript"></script>
<script src="Scripts/Base64.js" type="text/javascript"></script>
<%--<script src="Scripts/jquery.base64.js" type="text/javascript"></script>--%>
<script type="text/javascript">
function make_base_auth(user, pass) {
var tok = user + ':' + pass;
var hash = Base64.encode(tok);
return "Basic " + hash;
}
$(document).ready(function () {
var username = 'user';
var password = 'ppp';
var auth = make_base_auth(username, password);
$.ajax({
type: "GET",
dataType: "jsonp",
contentType: "application/javascript",
xhrFields: {
withCredentials: true
},
cache: false,
crossDomain: true,
beforeSend: function (xhr) {
xhr.setRequestHeader("Authentication", auth)
},
data: { 'inputData': "{PatientID:'12',FromDateTime:'05/21/2013 1:28:15 PM',ToDateTime:'05/21/2013 1:28:15 PM',ResponseType:'json',CompressResponse:'false'}" },
url:"http://192.168.15.160/RestAPI/Service.svc/GetMedicationValues",
success: function (jsonData) {
console.log(jsonData);
},
error: function (request, textStatus, errorThrown) {
console.log(request.responseText);
console.log(textStatus);
console.log(errorThrown);
}
});
});
</script>
Problem : I am getting login pop up when running the client application.I get the output only when i provide correct credentials on the pop up, irrespective of what credentials i pass in the request header.I have come through people asking this question a lot.Have anyone been able to solve this issue ? Thank You.
JSONP doesn't work with basic authentication.
If you don't need cross-domain request, use json as datatype.
Alos note that since JQuery 1.7, there are now two options for authentication : userName and password.
If the server performs HTTP authentication before providing a
response, the user name and password pair can be sent via the username
and password options.

Categories