Moqui REST API call fail with error code 403 - moqui

From my Angular 2 application I am trying to get data from Moqui but the request always fails with the error code 403.
Here is the REST API call implementation
getExample() {
let url = 'http://localhost:8080/rest/s1/example/examples'
let headers = new Headers({ 'Authorization': 'Basic
am9obi5kb2U6bW9xdWk='});
headers.append('Accept', 'application/json, text/plain, */*');
headers.append('Content-Type', 'application/json; charset=UTF-8');
let options = new RequestOptions({ headers: headers });
let response = this.http.get(url, options).map(res => res.json());
return response;
}
The Moqui logs :-
REST Access Forbidden (no authz): User null is not authorized for View on REST Path /example/examples
There is also a similar question Moqui Rest Nginx but from the answer I do not know that where I have to change the settings in Moqui.
On the client console the error is :-
XMLHttpRequest cannot load http://localhost:8080/rest/s1/example/examples. Response for preflight has invalid HTTP status code 403
But with a rest client like YARC it works :-

You must authenticate for REST API calls except for Service REST API paths that are configured to not require authentication (like the /mantle/my end points in the mantle.rest.xml file in the mantle-usl component).
You have authentication but then there is one other step: authorization. In general if authc is required then authorization is also required. This is done with database records usually either in seed data and can also be added using the System app that is included in the default Moqui runtime (ie the moqui/moqui-runtime repository).
There is an example of authorization setup for Service REST API calls in the MantleSetupData.xml file. The main difference from screen authorization is that the artifact type to use is 'AT_REST_PATH'. Here is that file on GitHub (right near the top of the file):
https://github.com/moqui/mantle-usl/blob/master/data/MantleSetupData.xml
The best documentation for most things to do with REST requests in Moqui, is currently in the comments in the 'rest.xml' file that actually processes the incoming requests (ie handles the /rest path). You can see this on GitHub here:
https://github.com/moqui/moqui-runtime/blob/master/base-component/webroot/screen/webroot/rest.xml

Related

how to skip Preflight Requset in vue with content-type:application/json

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.

Calling uber API

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.

ionic yii2 Response for preflight has invalid HTTP status code 500

I have a Ionic App and I'm trying to do a POST:
$http({
url: url+'/usuario/log',
method: 'POST',
data: {usuario : $scope.data.usuario, senha:$scope.data.senha},
headers : {'content-type':'application/json; charset=UTF-8'}
}).then(function(result) { ... });
On the server side I have a Yii2 application:
public function actionLog(){
header("Access-Control-Allow-Origin: *");
header("Access-Control-Allow-Methods: *");
header("Access-Control-Allow-Headers: content-type");
$params = json_decode(file_get_contents('php://input'),true);
$usuario = $params['usuario'];
$senha = $params['senha'];
...
}
But the error I got is always this, I send a POST and get a OPTIONS
OPTIONS http://www.nexusolucoes.com.br/personal/web/usuario/log
XMLHttpRequest cannot load http://www.nexusolucoes.com.br/personal/web/usuario/log. Response for preflight has invalid HTTP status code 500
The problem seems to be related with CORS, if the backend is on a different domain than the frontend the browser will always send an OPTIONS request first, to confirm that the cross domain sharing is allowed for the frontend domain.
If the browser gets a proper response for the OPTIONS, then, the POST request (the one you want) will be triggered as usual.
To sum up, you need to: Add a mapping on the URL Manager to respond to the OPTIONS verb for the exact same URL where you're sending the POST. Then, you need to create an action within a controller or to use the Yii's yii\rest\OptionsAction along with the CORS filters to allow the frontend domain to make the POST request.
Please check the following links for more information:
https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS
http://www.yiiframework.com/doc-2.0/yii-filters-cors.html
http://www.yiiframework.com/doc-2.0/guide-rest-controllers.html

Amazon Cloud Drive REST api endpoint

I am building a program that will list albums/folders and images from my Amazon Cloud Drive. I am able to authenticate and get a token by following the instructions here at amazon public apis.
I am having trouble with the next call to get my endpoints described here under Account API.
Using get
GET : {{metadataUrl}}/account/endpoint Gets the customer end-point against
which REST queries will be executed.
So my request looks just like this in fiddler and on my site just like it is described on the Amazon site here under Get Endpoint. The only differences is the token for obvious reasons.
Sample Request:
GET /drive/v1/account/endpoint HTTP/1.1
Host: drive.amazonaws.com
Authorization: Bearer
Atza|IQEBLjAsAhQ5zx7pKp9PCgCy6T1JkQjHHOEzpwIUQM
My response is:
{
"message":"Authorization header requires 'Credential' parameter.
Authorization header requires 'Signature' parameter.
Authorization header requires 'SignedHeaders' parameter.
Authorization header requires existence of either a 'X-Amz-Date'
or a 'Date' header. Authorization=Bearer"
}
What I am expecting:
{
"customerExists": true,
"contentUrl": "https://content-na.drive.amazonaws.com/cdproxy/",
"metadataUrl": "https://cdws.us-east-1.amazonaws.com/drive/v1/"
}
I did find some information about building the objects in my response from amazon, however, it's not listed in the documentation on the amazon developer site. Is this something new that has not been updated in the docs or am I doing something wrong?
I had a new line between Authorization: Bearer and my token Atza|IQEBLjAsAhQ5zx7pKp9PCgCy6T1JkQjHHOEzpwIUQM. After removing the new line my issue was fixed..

Rendr add custom header to fetch request (such as basic auth)

I'm building a Rendr app and I'd like to populate my user model by making a request to my API service's /login endpoint. That endpoint simply expects a basic auth header.
I see Rendr has an option to allow custom headers but the problem is the header is only added from the client to the Rendr node.js server. When the API proxy intercepts my requests and makes a call to http://my-api.com/login the basic auth header is not carried through to this request. I'm assuming the apiProxy ignores these headers- it has no way to know what header is custom.
How can I define a custom header client side and ensure the header is added to an API request?
this.app.fetcher.fetch({
user: {
model: 'User',
params: {}
}}, {
headers': {
"Authorization": "Basic abcdefg12345678"
}
}, function(err, user){
});
This example only adds a header from client -> Rendr node server, not NOT from Rendr node server --> my API service.
I put together an npm module for this: https://www.npmjs.com/package/rendr-api-proxy-optionable that should do what you need.
It allows pass throughs of request and response headers at the api proxy level.
Hope that helps!