Http post for login blocked with CORS


#1

Hello,

I don´t know if this has been answered already but I couldn’t find a match (with ionic 2)…

I’m getting this error:

No ‘Access-Control-Allow-Origin’ header is present on the requested resource

this is my current code:
public login(userName: string, userPwd: string) { let creds = "grant_type=password&username=" + userName + "&password=" + userPwd; let headers = new Headers(); headers.append("Content-Type", "application/x-www-form-urlencoded"); let url = this._config.Url + "/token"; // "http://localhost:20920/token"; this._http.post(url, creds, { headers: headers }) .map(res => res.json()) .subscribe( data => this.saveToken(data), err => this.logError(err), () => console.log("Autenticado usuario " + userName) ); }

By the way I’m a complete noob at ionic and angular, just trying to learn.:sweat:
Thanks in advance.


#2

You need the cordova-plugin-whitelist. Here’s an example of how to install and set it up:


#3

It is the server security error. Google it for your server.

For example for express:

if (app.get('env') === 'development') {
  app.use((req: Request, res: Response, next: NextFunction) => {
    res.header('Access-Control-Allow-Origin', '*');
    res.header('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept');
    next();
  });
}

#4

Thanks SDP1966 but, after installing that plugin I’m still getting the error, I´m sure that is because I´m doing something wrong…
I have added the following lines to config.xml:

<allow-navigation href="*" /> <meta http-equiv="Content-Security-Policy" content="default-src 'self' http:" />

I added those to the ‘widget’ root element don´t know if that´s the rigth place… :confused:

this is the request headers I´m sending:

Accept:/
Accept-Encoding:gzip, deflate, sdch
Accept-Language:en,es;q=0.8,en-US;q=0.6
Access-Control-Request-Headers:access-control-allow-origin, content-type
Access-Control-Request-Method:POST
Connection:keep-alive
Host:xxx
Origin:http://192.168.1.79:8100
Referer:http://192.168.1.79:8100/
User-Agent:Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.110 Safari/537.36

Response:
XMLHttpRequest cannot load http://xxx/token. Response to preflight request doesn’t pass access control check: No ‘Access-Control-Allow-Origin’ header is present on the requested resource. Origin ‘http://192.168.1.79:8100’ is therefore not allowed access. The response had HTTP status code 400.

I don´t really know if the request arrived at the server… I think not.

I don´t know if this info helps but I´m using a WebApi2 data service over an Azure website for the backend and I’m using ‘ionic serve’ to debug from local machine.

:sob:


#5

I tried but it did not fix it, using WebApi2 on Azure website and having configured the WebApi to allow all origins.

Thanks :sweat:


#6

The above goes in the header of your index.html file which you’ll find in your www folder.


#7

Hi @JorgeU0303 ,are you allow API to accept CORS ? In my case I do following ,
Add a class under App_Start CorsHandler.cs

using System.Linq;
using System.Net;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;

namespace NamespaceName
{
    public class CorsHandler : DelegatingHandler
    {
        private const string Origin = "Origin";
        private const string AccessControlRequestMethod = "Access-Control-Request-Method";
        private const string AccessControlRequestHeaders = "Access-Control-Request-Headers";
        private const string AccessControlAllowOrigin = "Access-Control-Allow-Origin";
        private const string AccessControlAllowMethods = "Access-Control-Allow-Methods";
        private const string AccessControlAllowHeaders = "Access-Control-Allow-Headers";

        protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
        {
            bool isCorsRequest = request.Headers.Contains(Origin);
            bool isPreflightRequest = request.Method == HttpMethod.Options;

            if (isCorsRequest)
            {
                if (isPreflightRequest)
                {
                    var response = new HttpResponseMessage(HttpStatusCode.OK);
                    response.Headers.Add(AccessControlAllowOrigin, request.Headers.GetValues(Origin).First());

                    string accessControlRequestMethod = request.Headers.GetValues(AccessControlRequestMethod).FirstOrDefault();
                    if (accessControlRequestMethod != null)
                    {
                        response.Headers.Add(AccessControlAllowMethods, accessControlRequestMethod);
                    }

                    string requestedHeaders = string.Join(", ", request.Headers.GetValues(AccessControlRequestHeaders));
                    if (!string.IsNullOrEmpty(requestedHeaders))
                    {
                        response.Headers.Add(AccessControlAllowHeaders, requestedHeaders);
                    }

                    var tcs = new TaskCompletionSource<HttpResponseMessage>();
                    tcs.SetResult(response);
                    return tcs.Task;
                }

                return base.SendAsync(request, cancellationToken).ContinueWith(t =>
                {
                    HttpResponseMessage resp = t.Result;
                    resp.Headers.Add(AccessControlAllowOrigin, request.Headers.GetValues(Origin).First());
                    return resp;
                });
            }
            return base.SendAsync(request, cancellationToken);
        }
    }
}

Add the bellow code in Global.asax.cs in Application_Start()

//Add CORS Handler
            GlobalConfiguration.Configuration.MessageHandlers.Add(new CorsHandler());

can you please try with this code ?


#8

First of all, I want to thank all you for the help, second I finally managed to make it work :grinning: but using the Azure Portal (there´s a section for CORS management that I did not know:


)

I´ve taken that image just in case someone gets to the same ‘trouble’.

Doing what SDP1966 posted about inserting the <allow-navigation… > to index.html was returning the error: The Content Security Policy ‘default-src ‘self’ http:’ was delivered via a element outside the document’s , which is disallowed. The policy has been ignored. I did then double check I had inserted that in the head section… and I did so I don´t know why it´s getting this error…

Doing what Kuntal posted didn´t seem to work either (didn´t debug so I´m not sure).

It seems that my issue was with Azure after all… and I´m not too sure how CORS works on Azure so another thing I will have to investigate :sleeping:


#9

hey guy, you should use proxy it will fix your problem

edit ionic.config.json file

{
  "name": "your project",
  "app_id": "85ffxxxx",
  "v2": true,
  "typescript": true,
  "proxies": [
    {
      "path": "/token",
      "proxyUrl": "http://192.168.1.152:9083/token"
    }
  ]
}

then

this._http.post("/token", creds, { headers: headers }).....

it only work on browser, if you want test on mobile please enter “http://192.168.1.152:9083/token” instead of “/token”


#10

It’s working in ionic serve
if i want to install in the ios and android
what changes i need to do


#11

in ios and android you should not be getting this error, see this ionic blog that explains the issue with details to solve it.


#12

Cors error can only be resolved from server side.
But yes for browser only we can resolved it by installing cors extension but for device can be only from server side