Http request fail on NativeScript Angular - angular2-nativescript

I have the Groceries tutorial, working. Then I go to the user service and change the URL of the login:
login(user: User) {
let headers = new Headers();
headers.append("Content-Type", "application/json");
return this.http.post(
"http://ws.u-vox.com/api/noauth/loginvenue",
JSON.stringify({
username: user.email,
password: user.password,
}),
{ headers: headers }
)
.map(response => response.json())
.do(data => {
Config.token = data.Result.access_token;
})
.catch(this.handleErrors);
}
handleErrors(error: Response) {
console.log(JSON.stringify(error.json()));
return Observable.throw(error);
}
When I press sign in I would expect a http message and a JSON on the terminal.
But instead I'm getting this mess, and I don't know what is happening.
CONSOLE LOG file:///app/shared/user/user.service.js:38:20: {"line":993,"column":38,"sourceURL":"file:///app/tns_modules/nativescript-angular/zone-js/dist/zone-nativescript.js","originalStack":"ZoneAwareError#file:///app/tns_modules/nativescript-angular/zone-js/dist/zone-nativescript.js:993:38\nfile:///app/tns_modules/tns-core-modules/http/http-request/http-request.js:86:37\nUIApplicationMain#[native code]\nstart#file:///app/tns_modules/tns-core-modules/application/application.js:211:26\nbootstrapApp#file:///app/tns_modules/nativescript-angular/platform-common.js:72:28\nbootstrapModule#file:///app/tns_modules/nativescript-angular/platform-common.js:60:26\nanonymous#file:///app/main.js:7:57\nevaluate#[native code]\nmoduleEvaluation#[native code]\n[native code]\npromiseReactionJob#[native code]","zoneAwareStack":"file:///app/tns_modules/tns-core-modules/http/http-request/http-request.js:86:37 [<root>]\nUIApplicationMain#[native code] [<root>]\nstart#file:///app/tns_modules/tns-core-modules/application/applicati
CONSOLE ERROR file:///app/tns_modules/nativescript-angular/zone-js/dist/zone-nativescript.js:569:26: Unhandled Promise rejection: Animation cancelled. ; Zone: <root> ; Task: null ; Value: Error: Animation cancelled. _rejectAnimationFinishedPromise#file:///app/tns_modules/tns-core-modules/ui/animation/animation-common.js:98:31 [<root>]
My endpoint works outside NativeScript app:
HTTP/1.1 200 OK
Server: nginx/1.10.3 (Ubuntu)
Content-Type: application/json
Transfer-Encoding: chunked
Connection: close
Cache-Control: no-cache, private
Date: Thu, 28 Dec 2017 15:00:39 GMT
Allow: POST
{"username ... }

I think this issue is due to CORS (cross domain) request.
First make sure the url on which you make the post request have its CORS enabled.
Second, if you are using iOS to run your app, add the following to /nativescript/App_Resources/iOS/info.plist:
<key>NSAppTransportSecurity</key>
<dict>
<!--Include to allow all connections (DANGER)-->
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>
For android I think there is an equivalent setting.

Related

REST API call is unauthorized

I am trying to make a REST API call from my .Net MAUI mobile app.
First I log in, and get a JwtSecurityToken:
JwtSecurityToken JwtToken = new JwtSecurityToken(authenticationResult.IdToken);
Then I try to use it to make a REST API call:
HttpClient client = new ();
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", JwtToken.RawData);
HttpResponseMessage response = await client.GetAsync(url).ConfigureAwait(false);
response.EnsureSuccessStatusCode();
This gives me an exception
Response status code does not indicate success: 401 (Unauthorized).
What is wrong or missing here?
ADDED:
Here is the respose:
{StatusCode: 401, ReasonPhrase: 'Unauthorized', Version: 1.1, Content: System.Net.Http.StreamContent, Headers:
{
client-request-id: 162ea393-a9b2-4e6b-9786-d6e18d18afb1
Date: Sun, 25 Dec 2022 20:42:26 GMT
request-id: 162ea393-a9b2-4e6b-9786-d6e18d18afb1
Strict-Transport-Security: max-age=31536000
Transfer-Encoding: chunked
Vary: Accept-Encoding
WWW-Authenticate: Bearer realm="", authorization_uri="https://login.microsoftonline.com/common/oauth2/authorize", client_id="00000003-0000-0000-c000-000000000000"
X-Android-Received-Millis: 1672000947348
X-Android-Response-Source: NETWORK 401
X-Android-Selected-Protocol: http/1.1
X-Android-Sent-Millis: 1672000947271
x-ms-ags-diagnostic: {"ServerInfo":{"DataCenter":"North Central US","Slice":"E","Ring":"3","ScaleUnit":"005","RoleInstance":"CH01EPF000051D6"}}
Content-Type: application/json
}, Trailing Headers:
{
}}
If you are developing your own API, you can then set this flag to true:
.AddJwtBearer(options =>
{
options.IncludeErrorDetails = true;
...
Then you will see a reason in the response why it failed:
HTTP/1.1 401 Unauthorized
Date: Sun, 02 Aug 2020 11:19:06 GMT
WWW-Authenticate: Bearer error="invalid_token", error_description="The signature is invalid"

Axios doesn't initiate POST request

I am using webdriverIO version 7 and axios in order to try to make login via API instead of doing it using UI.
This is my code:
getAuthToken({ email, password }) {
// axios
// .post('https://my-app.com/login', {
// j_username: email,
// j_password: password,
// CSRFToken: 'some-token',
// })
// .then((response) => {
// console.log('XXX');
// console.log(response);
// });
const data = {
j_username: email,
j_password: password,
CSRFToken: 'some-token',
};
axios({
method: 'POST',
headers: { 'content-type': 'application/x-www-form-urlencoded' },
data: qs.stringify(data),
url: 'https://my-app.com/login',
}).then((response) => {
console.log('XXX');
console.log(response);
});
}
I am trying to do it in both ways as above but I don't get ever response printed in the console.
I tried to do the request via Postman and it is working fine.
Also I am monitoring the traffic on the site via Fiddler Everywhere app and when this method gets executed, then nothing is shown in the Fiddler.
On the other hand when I do it via Postman, Fiddler catches it.
This is Raw Postman Request data:
POST https://my-app.com/j_spring_security_check HTTP/1.1
User-Agent: PostmanRuntime/7.28.0
Accept: */*
Cache-Control: no-cache
Postman-Token: 39311680-b11c-4a65-8ff7-2f03b97bf5eb
Host: my-app.com
Accept-Encoding: gzip, deflate, br
Connection: keep-alive
Content-Type: multipart/form-data; boundary=--------------------------619522728182415185770824
Cookie: anonymous-consents=%5B%5D; cookie-notification=NOT_ACCEPTED
Content-Length: 436
----------------------------619522728182415185770824
Content-Disposition: form-data; name="j_username"
email#test.com
----------------------------619522728182415185770824
Content-Disposition: form-data; name="j_password"
123456
----------------------------619522728182415185770824
Content-Disposition: form-data; name="CSRFToken"
some-token
----------------------------619522728182415185770824--
This is Raw Request when I do it through Chrome
POST https://my-app.com/j_spring_security_check HTTP/1.1
Host: my-app.com
Connection: keep-alive
Content-Length: 90
Cache-Control: max-age=0
sec-ch-ua: " Not A;Brand";v="99", "Chromium";v="90", "Google Chrome";v="90"
sec-ch-ua-mobile: ?0
Upgrade-Insecure-Requests: 1
Origin: https://my-app.com
Content-Type: application/x-www-form-urlencoded
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.212 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Sec-Fetch-Site: same-origin
Sec-Fetch-Mode: navigate
Sec-Fetch-User: ?1
Sec-Fetch-Dest: document
Referer: https://my-app.com/login
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.9
Cookie: JSESSIONID=some_id; dtCookie=some_data; anonymous-consents=%5B%5D; cookie-notification=NOT_ACCEPTED
j_username=ecx%40test.com&j_password=123456&CSRFToken=some_token
What am I doing wrong? Why it doesn't never log the response while doing it through axios?
Thanks!
The function is written correctly.
Postman passes additional details also which you can to look into.
Lets consider the scenarios which may cause the API call to fail:
Your function might not be correct.
The API is not configured properly.
Issues in the network.
Tackling the first scenario:
Check whether the function getAuthtoken() is getting invoked or not.
There might be an issue of CORS which you need to fix.
As you are send a JSON data, the server side must also accept the JSON data, or specify it in request headers. like
const data = {"name":"Example"}
axios.post('https://linkToApI.com', {
headers: {
'Content-Type': 'application/json',
'Authorization': 'some_auth_method_like_authToken',
specify other necessary headers
},
data
})
Getting to the second scenario:
Configuring the server is important.
make sure there is not any cors issue which is getting in the way.
make sure server is accepting the request data which you are sending.
make sure if the request fails it sends a error response.
Additional changes in the code for debugging purposes:
Whatever code you use please try to add a catch block as if the promise fails we can get the error message why is it failing. below is the example:
axios({
method: 'POST',
headers: { 'content-type': 'application/x-www-form-urlencoded' },
data: qs.stringify(data),
url: 'https://my-app.com/login',
}).then((response) => {
console.log('XXX');
console.log(response);
}).catch(e=>{console.log(e)}); // this will provide you with info why is it failing

What is fetch's redirect and authorization headers expected behavior? (Safari has different behavior from other Mac browsers)

In short, when using an authorization header with the fetch api and a redirect is followed Chrome, FireFox, and Opera (on a Mac) include the authorization header in the second request. However, Safari (12.0.1) does not. From the fetch api spec and issue #553 my understanding is that the header should be included. Is this a correct understanding of how fetch is supposed to work?
Here's the simplified code I'm using with a workaround for Safari but I'd like to know if there's something I'm doing wrong that's causing the behavior with Safari or if there is a better workaround.
export async function loadData(token) {
const opts = {headers: {Authorization: `Bearer ${token}`}, credentials: 'include', redirect: 'follow'};
let response = await fetch('/api/data', opts);
// Work around for Safari not including headers in redirected request
if (response.status === 401 && response.redirected) {
response = await fetch(response.url, opts);
}
if (response.ok) {
return response.json();
}
return null;
}
Quick edit some additional info about the redirect. The redirected location is to the same origin and is a 302:
content-length: 118
content-type: text/plain; charset=utf-8
date: Mon, 26 Nov 2018 20:12:18 GMT
location: /api/data/current-version
server: nginx
status: 302
strict-transport-security: max-age=15768000
vary: Accept

While trying to access RedHat BRMS kie server, i am not able to use POST/PUT methods through rest client

Trying to access POST data through rest client, getting 405.
The response headers states Allow: GET, OPTIONS, HEAD.
So how can I make my rest container accept POST/PUT methods?
EndPoint http://localhost:8080/kie-server/services/rest/server Request Headers used -
Content-Type: application/json
authorization: Basic !#$#%&$$(((
Accept: application/json
X-KIE-ContentType: JSON RESPONSE HEADERS
Server: Apache-Coyote/1.1
Allow: GET, OPTIONS, HEAD
Content-Type: text/html;charset=utf-8
Content-Length: 1088
Date: Thu, 01 Sep 2016 08:43:33 GMT
Tried using Advanced rest client,curl and java code but Same results :(
Referred - https://access.redhat.com/documentation/en-US/Red_Hat_JBoss_BRMS/6.3/html/Getting_Started_Guide/chap-Hello_World_rule_example.html
I think you have to change the Endpoint (URL). I would suggest
http://localhost:8080/kie-server/services/rest/server/containers/instances/("nameOfYourDeployment")
Or try without instances.
In Rest Client provide the following set of values:
URL:
http://localhost:8080/kie-server/services/rest/server/containers/instances/<name-of-your-container>
HEADER:
Accept: application/json
Content-Type: application/json
select method type POST and your JSON request payload
When you hit the API it will ask you for the username and password provide the credentials.
fou can send
payload
as:
{
"commands": [
{
"insert": {
"out-identifier": "Input",
"return-object": "true",
"object": {
"<complete-package-name>.<class-name>": {
"variable-1" : "value-1",
"variable-2" : "value-2"
}
}
}
},
{
"fire-all-rules": {
"outIdentifier": "output"
}
}
]
}

How can I prevent Ext JS from including an entity body in DELETE requests using a restful store?

When Ext JS issues a DELETE request from a restful store, it includes an entity body. Although this doesn't seem to be forbidden by the HTTP spec, Google App Engine doesn't accept such requests. So I'd like to know if there is a way to prevent a restful store from including a redundant entity body on DELETE requests.
Details:
Using this sample as reference:
http://www.sencha.com/deploy/dev/examples/restful/restful.html
This is how the store is defined:
var store = new Ext.data.Store({
id: 'user',
restful: true, // <-- This Store is RESTful
proxy: proxy,
reader: reader,
writer: writer
});
After pressing the "Delete" button, this is the request Ext JS sends:
DELETE http://www.sencha.com/deploy/dev/examples/restful/app.php/users/6 HTTP/1.1
Host: www.sencha.com
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 6.0; pt-BR; rv:1.9.2.4) Gecko/20100611 Firefox/3.6.4 (.NET CLR 3.5.30729)
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: pt-br,pt;q=0.8,en-us;q=0.5,en;q=0.3
Accept-Encoding: gzip,deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive: 115
Connection: keep-alive
Content-Type: application/json; charset=UTF-8
X-Requested-With: XMLHttpRequest
Referer: http://www.sencha.com/deploy/dev/examples/restful/restful.html
Content-Length: 10
Cookie: bb_sessionhash=8d75f5e42d576fb695a02bf1d24c9ff1; etc...
{"data":6}
When a request in this format (with the "data" content) is submitted to Google App Engine, it replies with:
400 Bad Request
You can fix this problem, as you guessed, by overriding a method in the HttpProxy class. First, add this code:
// Special HttpProxy that sends no body on DELETE requests
Ext.data.GAEHttpProxy = Ext.extend(Ext.data.HttpProxy, {
doRequest: function(action, rs, params, reader, cb, scope, arg) {
if(this.api[action]['method'].toLowerCase() == "delete") {
delete params.jsonData;
}
Ext.data.GAEHttpProxy.superclass.doRequest.call(this, action, rs, params, reader, cb, scope, arg);
}
});
Then, use this new class ("GAEHttpProxy") instead of HttpProxy in the rest of your code (for instance, when you create the proxy you use in your store shown above). This worked for me, and I hope it works for you!
Although the question is asked 7 years ago and we have sencha 6 now, the problem isn't solved OOTB yet. So here is my working solution:
Ext.define('My.Proxy', {
extend: 'Ext.data.proxy.Rest',
writer: {
type: 'json',
writeAllFields: true, // may be false, as you wish
transform: {
fn: function(data, request) {
return request.config.action === 'destroy' ? null : data;
},
scope: this
}
}
});
We could also do this check: request.config.method === 'DELETE' but for some reason it always returns false. So I recommend to stay with action === 'destroy'