I'm trying to interrogate a rest service. If I use CURL I can get the data back without issue.
curl -k -X GET -H "Accept: application/json" -u username:password "https://example.com/v1/apps"
However, I've tried several methods for pulling data back using Angular's $http and $resource services and nothing seems to work.
Does anyone have a good example of how to do this with Angular 1.4.6?
It's both a Cross-Domain and Basic Authentication call.
There are so many "like" examples out there, but nothing seems to work.
Hopefully this will save someone else some frustration. A few things were causing the issue.
The certificate on the target site was invalid. They were using a self-signed cert with example.com as the domain.
The call I was using had a capital 'GET' in it, it should be all lower-case.
To solve issue 1, I had to add the server's IP to my hosts with an alias example.com. It's a major hack, but it was necessary to get around the invalid domain issue. I'm working with the server's owners to have a correct cert put in place.
For the call itself, here an example that works. I'm using another service for the auth header. It just base64s the username and password. Replace AuthorizationService.getCredentials() with your favorite base64(username:password) tool. There are several of them out there.
.factory(
'ApplicationDetailService',
[
'$resource', 'AuthorizationService',
function($resource, AuthorizationService) {
return $resource('https://example.com/v1/apps/:id', { id: '#id' },
{
'get' : {
headers: {
Authorization: AuthorizationService.getCredentials()
}
}
}
);
}
]
)
Finally, because the target server wasn't passing back the Access-Control-Allow-Origin: * header in its response. All of the modern browsers to flat out reject the AJAX return.
I was under the assumption that it was an Angular thing, I was wrong. There's a plug-in for Chrome called Access-Control-Allow-Origin: *, I tried that, it failed because CORS needs your domain in the header.
I found a flag for chrome --disable-web-security that tells Chrome to ignore all security. FAIR WARNING: This makes your session very insecure. Only do this for a test environment. Just modify your shortcut to pass the flag in as a parameter to chrome.exe.
With all of that, I was able to get past my issue and continue developing until the server team fixes things on their end.
Best of luck!
Related
I have a nodejs express server running on app engine.
If i make a GET request to https://astral-pursuit-252600.appspot.com/users in the browser it works fine to say unauthorized (401).
If I do the same GET request in postman it returns 400 bad request.
Is there any obvious reason why this is occurring?
This is a known issue with postman. This tool sends certain headers by default that you cannot remove. App Engine does not like them for some reason. I had to use the Insomnia tool instead which does not include default headers.
The first thing that I can think about is that, in order to do an API call, you need to use an API key in your request. You should create one, after that you need to obtain an access token. Your requests should be send to an address like https://astral-pursuit-252600.appspot.com/users?key=YOUR_API_KEY and include in your request a header to contain the access token. Something like this : --header 'authorization: Bearer YOUR_ACCESS_TOKEN'.
In order to do that I do not think you need to change manually each request, but you need to change some POSTMAN settings. You can find here a guide with exactly what setting should be changed for this use case.
You can see more details about this topic and a more detailed guide for doing an API calls here.
In case this was not the issue, could you please provide me your POSTMAN settings? I am pretty sure this is about the way POSTMAN does the requests anyway.
I access a server that I can change in any way. It is only available to me.
GETS / POSTS work in curl, but I get an error in my angular web app
I read a ton of posts about this, and after nothing seemed to work, I installed the CORS extension to Chrome, added *://*/*, and I have to turn it on anytime I'm trying to access the server. But it works.
Most of the posts say this is because the server does not allow access from outside sources. So I did some more digging and found the W3 CORS enabled site, that specifies a filter must be added.
However, when I get the error, I can open the network panel and see that the response came back exactly as I was expecting, so why did I get an error?
This makes it seem like Chrome is not allowing access.
Why must the server be changed to allow this?
Does this mean anyone with this chrome extension can access my server?
It seems like it should be possible to configure a header in my $http.get that would allow this, but everyone keeps saying its the server...
Cross domain calls are not allowed by default. When the browser makes a call to a website or Web-API sitting on a different domain than the domain opened on the browser, it includes a HTTP header "Origin" in the request. The server looks at this header and if it's white-listed it includes the header Access-Control_Allow_Origin in the response. All this happens in a pre-flight request using HTTP Options method before the actual GET/POST call. So for the CORS to work the server has to allow the client domain, so the browser can make further calls.
When I make an $http.post request and set the "withCredentials" property to true.
My request works fine in Chrome and Fiefox. However, I'm getting the error below in IE:
XMLHttpRequest: Network Error 0x80070005, Access is denied.
I noticed that if I enable the "Access data resources across domains" setting in IE, The error gets resolved. However I need to find an alternative solution because I can't ask the users to enable that setting obviously.
I noticed that a $http.get request to the same domain is working in IE with no issue, the issue is only with the $http.post request, the Options request is getting a 500 internal server and I see the request and response headers below:
Note:
I do have the necessary custom headers, and I can see them in Chrome when the OPTIONS request succeeds. The headers that I see in Chrome are listed below:
Could you please let me know if I'm missing something that would make the request work in IE without having to enable Access data sources across domains?
Internet Explorer 9 doesn't support cookies in CORS requests. The withCredentials property of the $http arguments attempts to send cookies. I don't think there's any way to fix it with headers. IE10+ should work by default, just be sure that you are not in compatibility mode. CORS isn't fully implemented in IE10 either, but the type of request you are trying to do should work.
You didn't mention what the nature of your web app is, but it impacts the type of workaround you will need for IE9. If possible, see if you can refactor your code to use a GET request instead (again, I don't know what you are trying to do via AJAX so this may be impossible).
You may be able to use Modernizr or something similar to detect if the browser supports CORS. If it is not supported, send the request without AJAX and have a page refresh.
Another alternative if you really want to use AJAX is to set up a proxy on your web server, i.e. the server on the same domain. Instead of making the cross-origin request directly, you make the AJAX request to your same-origin server, which then makes the request to the cross-origin server for you. The server won't have CORS issues. This solution assumes, of course, that you have some server-side scripting going on such as PHP, Node or Java.
I have a SPA implemented in Angularjs - Typescript calling VSO API and providing authentication data you can find below:
((): void => {
"use strict";
angular
.module("app")
.config(config);
config.$inject = [
"$httpProvider"
];
function config(
$httpProvider: ng.IHttpProvider
) {
$httpProvider.defaults.headers.common['Authorization'] = "Bearer username:password";
}
});
I see the Network tab of the browser that this call will be redirected to here:
https://app.vssps.visualstudio.com/_signin?realm=dldxdm.visualstudio.com&reply_to...
And a following request.
The console does not show any authentication error, but there is no result of my request (GET) but it should be! Instead of the result I get the message you can see in the screenshot. It is Microsoft Internet Explorer's Enhanced Security Configuration is currently enabled on your environment. This enhanced level of security prevents our web integration experiences from displaying or performing correctly. To continue with your operation please disable this configuration or contact your administrator. But the query executed in Chrome. Why an IE error message is here?
In the browser I logged in to VSO to the project, and if I copy the url and paste into another tab and execute it I'll get the proper result I'm looking for.
Questions:
why there is no result for my query executed by Angular app?
how should I authenticate for VSO? I cannot set up a token because it runs on localhost currently.
I googled for the IE error message but there is no answer. The how to disable the enhanced security of IE I have found Windows Server answers. I don't think they are related to my issue.
Update:
Ok, I have an article about what is happening. Next step, implementation.
I found that this happened to me when my PAT was wrong due to a copy and paste error.
Looks like you are probably failing authentication because you didn't base64 encode the bearer token.
Prefix your Personal Access Token(PAT) with :(colon). then Base 64 encode it.
Eg:
If "myaccesstoken" is my PAT,
Apply base 64 encoder to ":myaccesstoken"
In the Authorization header, place your base encoded string as,
Authorization : Basic MyColonPrefixedBase64String
I had this same issue. I verified this in postman as follows...
I didn't have to base64 encode my PAT.
I found that I just needed to double check that my PAT had the right access.
I passed the data as Basic Auth.
Username: "whatever the hell you want"
Password: PAT
Response: 200 👍
If somebody else comes on this page after getting same error in Azure devops classic pipeline (like I did) then they may need to select radio button titled "Allow scripts to access the OAuth token". This option is available here "Stage >> Agent Job >> Additional Options". For more clarity, you may wan to refer this blog post.
I need to make an ajax call to a server which uses a self-signed certificate.
Using the --insecure option does in curl helps in doing so.
But i need to make ajax calls, much like the $http requests in angular js. Are there any headers that can be set so that the error of the certificate does not arise.
There is a very hackish way in which you can point your browser in the direction of the server resource. This will prompt you to proceed with caution and upon proceeding anyway (try it with Chrome), your queries to the server should now work since the browser will now remember that that particular certificate is okay. I had this issue in the last project I worked on with self signed certs.