I am trying to perform some actions on the Tableau server via REST API for which I require the Auth token. I tried using the signin API from Postman and it works like a charm. However the same code is giving "Bad Request" error whe tried calling from javacript code from my webpage.
var dataVal = {
"credentials": {
"name": "admin",
"password": "admin",
"site": {
"contentUrl": "MySite"
}
}
};
$.ajax({
contentType: 'application/json',
data: JSON.stringify(dataVal),
dataType: 'jsonp',
success: function (data) {
console.log("call succeeded");
},
error: function (request, textStatus, errorThrown) {
console.log(request.getAllResponseHeaders());
},
processData: false,
type: 'POST',
url: 'http://mytableauserver/api/2.6/auth/signin'
});
The above code return token, siteid, userid from postman but return ""BAD REQUEST" error from javascript code. Any pointers will be highly appreciated.
For anyone else looking, Tableau now supports CORS but only on Tableau Server at this point.
Enabling CORS on Tableau Server for the REST API
For security, most web browsers restrict HTTP requests to the same origin. That is, to
access a resource on a server through an API, the request must come from the same
origin (server), or a proxy must be set up to handle the request.
Tableau Server now supports Cross-Origin Resource Sharing (CORS), so you can do away
with your proxy and call the REST API from the browser. The CORS mechanism is
currently only enabled for Tableau Server, and can be turned on by server
administrators in a couple of steps using the TSM command-line tool. To learn more,
see the description of the vizportal.rest_api.cors.allow_origin option in tsm
configuration set Options. As a security measure, you should make API calls to Tableau
Server using the HTTPS protocol (SSL or TLS). See Using HTTPS (SSL/TLS) for API Calls.
Add the origins that need access to the Tableau Server.
Determine the origins (servers) you want to allow access to the REST API, and use the
tsm configuration set command with the vizportal.rest_api.cors.allow_origin option.
For example, to grant access to one two origins, https://mysite and https://yoursite,
you would stop the server (tsm stop) and then use the following command:
tsm configuration set -k vizportal.rest_api.cors.allow_origin -v
https://mysite,https://yoursite
You can enter multiple origins. Use a comma to separate the entries.
Note: You could also use an asterisk (*) as a wild card to match all sites. This is
not recommended as it allows access from any origin that has access to the server and
could present a security risk. Do not use an asterisk (*) unless you fully understand
the implications and risks for your site.
Enable CORS on Tableau Server.
Use the tsm configuration set command with the vizportal.rest_api.cors.enabled option.
The default setting is false, so set this to true as follows:
tsm configuration set -k vizportal.rest_api.cors.enabled -v true
Update your Tableau Server configuration (tsm pending-changes apply) to restart
Tableau Server and make the changes take effect. Only the origins you specify will
have access.
https://help.tableau.com/current/api/rest_api/en-us/REST/rest_api_concepts_fundamentals.htm
Related
In my next.js project I'm trying to send a POST request using axios:
axios.defaults.baseURL = "https://{my-server-url}/api";
useEffect(() => {
axios({
method: "POST",
url: "/build_pages",
data: {
page_id: 3,
},
}).then((res) => {
console.log(res.data);
});
}, []);
I'm getting the following CORS error:
My server is [laravel] php and is deployed on cpanel, but before I deployed my backend to cpanel (i.e. when I was working on localhost) I did not get this error.
How do I turn off this error (note that I don't want to download any web browser extension to fix the CORS error)
I came across this link but it does not say where (which file) to add it to so I'm stuck
Edit: I tried the middleware solution provided in this answer: https://stackoverflow.com/a/69151121/12009071 but also it didn't work, howerver the error changed to:
Access to XMLHttpRequest at 'https://{my-server-url}/api/check_admin_login' from origin 'https://{my-server-url}.vercel.app' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: It does not have HTTP ok status.
This is an API-side error. You have to allow cross origin requests on the API server. Based on your question, I assume your API is NOT the Next.js project.
Therefore, you should check the settings of your server. The next.js POST call is not the issue.
I've set up an express basic auth using the express-basic-auth module.
const basicAuthFunc = basicAuth({
challenge: true,
users: { 'admin': s.BASIC_AUTH.ADMIN_PASS }
})
it works on localhost. I'm prompted with a popup js challenge.
i'm deploying to lambda function and using AWS API gateway.
the page does not present me with the challange. I just get the 401 directly.
I tried removing the basic auth and the page loads so it's just related to the basic auth.
what headers should I add to api gateway ?
tried this one :
https://medium.com/#Da_vidgf/http-basic-auth-with-api-gateway-and-serverless-5ae14ad0a270
adding WWW-Authenticate and 'Basic' to 401 response.
didn't work
error :"405 not allowed Method" in post method type call in request command vue
i need call api function with content-type:application/json and post Method type with request command in vue ,but browser add preflight request with options method type and it causes this error :"405 not allowed Method"
var options = {
method: "POST",
url: "http://api.sample.com/login",
headers: {
"Access-Control-Request-Method":"POST",
"cache-control": "no-cache",
"content-type": "application/json",
},
body: '{ Username: "demo", Password: "demo", Domain: "test" }'
};
request(options, function(error, response, body) {
if (error) throw new Error(error);
body.data;
alert("ok");
});
The OPTIONS call is done whenever you do a cross-origin request. This means the domain your application is running on is different from the domain where the api is. A pre-flight request is mandatory for these requests, because the browser needs to figure out if you are allowed to do these requests. A 405 error means that the server thinks you are not allowed to make that request.
To solve this problem you can move your api to the same domain as your frontend. Please note that it cannot be on a subdomain.
A different way of solving this, is by sending back the correct headers. In your case you seem to at least miss the Access-Control-Allow-Methods response header. Make sure to send this header and either dynamically figure out which methods are allowed, or do something like the following. That would allow the most common methods to work.
Access-Control-Allow-Methods: GET, POST, PUT, DELETE
In the comments you said that you do not have control over the api, and as such cannot change the response header. In that case your best bet is to contact whoever maintains the api and ask how to best use their api.
In the comments you said that this worked fine when you did the same thing in ASP.NET. ASP.NET is a server-side language, which means that requests in that context do not have a concept of "cross-origin". Cross-origin only comes into play in the browser, where the application runs on an actual domain.
Assuming you can set up a proxy on your application domain, you can also create a proxy that proxies all requests to the api you actually want to communicate with. You would deploy your domain on https://example.com and do your requests to https://example.com/api/endpoint. Your proxy will listen for requests that begin with https://example.com/api and proxy it to https://whatever.the.api.is/ with the appropriate endpoint and data.
Please keep in mind that while some api's might just be configured incorrectly, a lack of cross-origin response headers might just mean that the api is nog meant to be consumed through the browser. Part of this could be that the request contains a secret that should not be exposed to users that use your application, but should instead only be on the server. Using a proxy in that case would set you up for impersonation attacks, because you would expose the secret to your application, but defeat the cross-origin headers by making it appear to the application that the api is on the same domain.
I've just started implementing Authentication in my Web API.
I want to start with Basic Authentication
I learned that i've to pass Username and Password in every request.
So, lets say i'm doing some Admin task and making API call for same like this:
$.ajax({
url: host + "homework/delete/" + $(this).data("id"),
type: 'DELETE',
headers:
{
Authorization: 'Basic ' + btoa(username + ':' + password)
},
success: function (d) {
$tr.remove();
},
error: function () {
alert("Error please try again");
}
});
So, although my username/password is in variable, but their value must be at page(source). whosoever access that page, can see those credentials.
That means, whosoever get to know the url of that page, can see the credentials.
If i put a login page, how should i check on admin page that this user is authenticated. Should i use Cookies? to set something if user is coming through login page?
To enhance security, I think there should be another approach. At first you need to authenticate to you service using username and password, and receive authentication token with limited lifetime, then you should use this token to access your services.
I think you have to choose another approach:
create a server side application with UI (PHP, Java, ...)
this application has a session management
the credentials are stored in the configuration of the server side app
the requests to the service which is secured by Basic Authentication are performed by the server app. The responses are delivered to the client
You can't hide the credentials if you are creating a client side JavaScript application. Another issue with your approach maybe this: does the secured service support CORS (cross origin resource sharing) ?
When I call ubers API from my front end, the call gets blocked with the following error: No 'Access-Control-Allow-Origin' header is present on the requested resource. However, when I call from a node js application the call goes through just fine. The code is the exact same. See below:
$.ajax({
url: "https://api.uber.com/v1/estimates/price",
headers: {
Authorization: "Token " + uberServerToken
},
success: function(result) {
};
This is due to CORS policy enforced by the browser. For cross domain requests the server must include a header Access-Control-Allow-Origin: *. This is likely on purpose as you should never include a server tonken in your client code. For the client you should be using a bearer token. Take a look at the Uber API documentation.
Since the server is at your own control you're free to make API requests to anywhere.