I've been researching ways to send AJAX POST requests to my API and I'm trying to understand how to pass basic auth credentials correctly.
Interface API
https://www.example.com/app/ -------> https://api.example.com/
Using this example I found on StackOverflow--couldn't anyone view the source of the JS, see my username and password in cleartext, and have access to all my API functions?
If so, how do I pass my username and password without showing it to the world?
$.ajax({
url: 'yoururl',
username : username,
password :password,
type: 'POST',
contentType: 'application/x-www-form-urlencoded',
dataType: "text",
xhrFields:
{
withCredentials: true
},
beforeSend: function (xhr) {
xhr.setRequestHeader('Authorization', 'Basic ' + btoa(username + ":" + password));
}
});
Yes, if you hardcode your username and password in your JavaScript, the whole world will be able to see them and use them.
You should not use basic authentication to protect web APIs. There are several alternatives as I describe in this answer. My preference is with OAuth2. Using it from a JavaScript client, you want to look at the implicit flow, which is specifically for untrusted clients.
Related
In my website, something weird is happening while running in Internet Explorer. My website and API are hosted separately. API is having anonymous authentication with token based authorization. MVC website is having windows authentication. Most of the times everything works as expected. But sometimes what happens is while calling the API from javascript my Authorization is headed changed to NTLM instead of Bearer. I am giving some screenshots of the same scenario.
Successful API Call:
401 Unauthorized Call:
My Ajax is as follows:
$.ajax({
url: src,
type: 'GET',
cache: false,
async: true,
data: (parameters),
headers: {
'Authorization': 'Bearer ' + sessionStorage.getItem('token')
},
contentType: 'application/json'
dataType: 'json',
success: successCallback,
error: function (xhr, textStatus, errorThrown) {
ErrorPopup("error occur");
}
,
beforeSend: function (xhr, settings) { xhr.setRequestHeader('Authorization', 'Bearer ' + sessionStorage.getItem('token')); }
});
I have debugged all API calls and always authorization header is set to Bearer ... still, somehow some way NTLM is taking control of it and making my API calls unauthorized. Please share some insights how could I solve this. I cannot change authentication in IIS as it's beyond my control. If you need any more inputs I can provide that too.
It looks like there is a redundancy in your authorization headers (headers array + beforeSend). Remove one of them and test (reason : RFC 2616 says that several headers with the same name should be concatenated on the same line, and maybe the server is replying with an NTLM authorization request to such a request that it doesn't allow).
I'm having issues making an authenticated Jenkins API call - I'm trying to retrieve some JSON data. I'm using it on a webpage with jQuery - anyone with Jenkins experience, any ideas?
Note: the password is the user API key from Jenkins.
$.ajax
({
type: "GET",
url: "http://jenkinsurl/build3/testReport/api/json",
dataType: 'jsonp',
username: "jenkinsusername",
password: "1axxxxsdasde3ad8",
success: function (){
alert('To test it worked');
}
});
Thanks
I've been doing something similar; ran into all sorts of issues. Documentation is scanty on this sort of thing. But finally got it working, at least on my Jenkins. There's a possibility that the following won't work with every Jenkins authentication plugin; I've only tested against the built-in authentication and the scripted authentication.
To authenticate, do the following in your java script:
$.ajax(jenkins_relative_url + 'j_acegi_security_check', {
type: "POST",
dataType: "text",
async: true,
headers: {
"Content-type": "application/x-www-form-urlencoded"
},
data: {"j_username": username, "j_password": password},
});
The ajax call above would get cookies loaded up that Jenkins uses to determine if you are authenticated. After that, you could do the same $.ajax calls you where making, but without the username and password parameters. You should only need to authenticate once, then make any number of calls against Jenkins - as long as you carry around those cookies.
I'm trying to access an API service (via XMLHttpRequest/ajax) hosted on a sub-domain (ie: a client on app.samedomain.com will call out to api.samedomain.com) that requires specific headers to be set for security purposes, but I keep getting Access is denied errors. All the solutions I've found say the client/end user must add the site to the "Trusted Sites" security zone, but obviously this is not a real solution. What do I need to do to access an external site with specific headers?
Example Code:
var getUserById = function (user, callback, error) {
$.support.cors = true;
var endpoint = _getApiVersion() + '/person/model/' + user.userId;
var _headers = _setHeaders(endpoint, null, user, 'GET');
$.ajax({
type: 'GET',
beforeSend: function (request)
{
request.setRequestHeader("api-key", _headers['api-key']);
request.setRequestHeader("timestamp", _headers['timestamp']);
request.setRequestHeader("content-md5", _headers['content-md5']);
request.setRequestHeader("content-type", _headers['content-type']);
request.setRequestHeader("signature", _headers['signature']);
request.setRequestHeader("Access-Control-Allow-Origin", "*");
},
url: _getBaseUrl() + endpoint,
data: null,
contentType: 'application/json',
dataType: 'json',
success: callback,
error: error
});
};
Thanks in advance,
Dan
Are you trying to get data that is not in the same domain as the requester? If that is the case the only option is to proxy the original request via a service so XMLHttpRequest has access to it.
"Access-Control-Allow-Origin" is a response header, not a request header. It is something that the server should send back to IE as part of the response.
If that still doesn't work, you might want to try firing up the F12 Network tool in the IE Dev tools to see if you can get more detail into where in the process the request is failing (Ex: It might be failing on a CORS preflight OPTIONS request).
Also, Rather than using "Access-Control-Allow-Origin: *", you should use "Access-Control-Allow-Origin:app.samedomain.com" to control which domains can access the API
To read more about CORS, check http://www.w3.org/wiki/CORS
Aside from that, it feels like an order of operations thing. All this should be before the callbacks.
type: 'GET',
url: _getBaseUrl() + endpoint,
data: null,
contentType: 'application/json',
dataType: 'json',
I would like to call OData .NET web service that authenticates users via basic authentication.
I use following ajax call:
var fullUri = APIUri + "?$format=json";
$.ajax({
url: fullUri,
contentType: "application/json",
dataType: "jsonp",
type: 'GET',
jsonp: '$callback',
beforeSend: function setHeader(xhr) {
xhr.setRequestHeader('Authorization', token);
},
success: callback,
error: function (xhr, ajaxOptions, thrownError) {
alert(thrownError);
},
});
The results are unusable for me:
Calls are blocked because of CORS (until I will paste API url and try to load it in chrome). I tried local html file and html file uploaded to the same domain/port, but authentication fails (according to Chrome console).
Once I enter service URL into chrome address bar, I am asked to provide login name and password by Chrome. If I enter them, they are cached and used even I assign them in beforeSend. How to blocks this behavior?
I've tried a lot of examples how to configure jsonp, headers etc, but did not find working solution yet.
IIS server response header is also configured using "Access-Control-Allow-Origin" value="*".
You can set the HTTP Password and Username in the AJAX Call directly:
$.ajax({
url: fullUri,
contentType: "application/json",
username: <login>,
password: <password>,
...
Use the following to support CORS:
jQuery.support.cors = true;
Regarding the call, are you using HTTPS? Is the certificate valid?
I'm having an issue getting this jQuery.ajax call to work. When the script executes I get an error (textStatus = "error"), but no error message (errorThrown = "").
$.ajax({
type: 'GET',
url: 'http://www.kanbanpad.com/api/v1/projects.json',
username: 'user#example.wtf',
password: 'myAPIkey',
dataType: 'json',
success: function(data) {
alert(data);
},
error: function(jqXHR, textStatus, errorThrown) {
alert(textStatus+': '+errorThrown);
}
});
If I manually hit the API URL (above) and type in my login credentials, I do get the proper JSON response. So, I'm not sure what I'm doing wrong. Is my code malformed?
If you need more information about the API, go to http://www.kanbanpad.com/api/v1
That page is using HTTP basic auth but you are simply posting a username/password in your request. You have to properly set up the auth tokens and pass them in a header. Here is a simple tutorial on HTTP basic auth over AJAX--notice there is a jQuery specific example for the AJAX part.
Here is the fix:
Change URL value to http://username%40domain.com:apikey#www.kanbanpad.com/api/v1...
For whatever reason, jQuery (1.5.1, also tried with 1.4.4) is not passing the username and password parameters to the web server correctly (or not at all?), so rather than use those parameters, it can authenticate by including the credentials in the URL string.
use secured protocol for URL: https://www.kanbanpad.com/api/v1/projects.json, not http