7

I have a backend on ASP.NET Core Web API and frontend on Angular 9. I am implementing google authentication. In postman It works fine, but in my angular app when I try to authorize via google I get error:

Access to XMLHttpRequest at 'https://accounts.google.com/o/oauth2/v2/... 
(redirected from 'https://localhost:44340/api/auth/googlelogin')
from origin 'http://localhost:4200' has been blocked by CORS policy: 
Response to preflight request doesn't pass access control check:
Redirect is not allowed for a preflight request.

CORS configuration on backend:

            services.AddCors(options =>
            {
                options.AddPolicy("MyPolicy",
                      builder =>
                      {
                          builder
                          .WithOrigins(Configuration["ApplicationSettings:Client_URL"].ToString())
                          .AllowAnyOrigin()
                          .AllowAnyHeader()
                          .AllowAnyMethod();
                      });
            });
            app.UseCors("MyPolicy");

Method in my service

        public ChallengeResult LoginViaGoogle()
        {
            var provider = "Google";
            var redirectUrl = "/api/auth/ExternalLoginCallBack";
            var properties = Database.SignInManager.ConfigureExternalAuthenticationProperties(provider, redirectUrl);
            return new ChallengeResult(provider, properties);
        }

Method in my controller

        [HttpGet("GoogleLogin")]
        public IActionResult GoogleLogin()
        {
            ChallengeResult result;
            try
            {
                result = _authService.LoginViaGoogle();
            }
            catch(Exception ex)
            {
                throw ex;
            }
            return result;
        }

My method in Angular:

  googleLogin(){
    const httpOptions = {
      headers: new HttpHeaders({
        "Access-Control-Allow-Origin": "*"
      })
    };
    return this.http.get("https://localhost:44340/api/auth/googlelogin", httpOptions);
  }

I have tried a lot of solutions from this website, but none helped.

I think that the problem may be that I incorrectly registered the URL in google oauth. enter image description here

13
  • what is the value of Client_URL in your appconfig file? Commented Jun 25, 2020 at 11:39
  • @bthn http://localhost:4200, everything works fine except google authentication. Commented Jun 25, 2020 at 11:40
  • I think google can not send request to your localhost. you should buy or use a free domain and host your applicaiton and give that domain to google. Commented Jun 25, 2020 at 11:44
  • I am not sure but maybe you can also try using ngrok to make google auth work with localhost. Commented Jun 25, 2020 at 11:46
  • @bthn but If i went to my api uri https://localhost:44340/api/auth/googlelogin in browser or in postman I can authorize and get token, so I think problem is not connected to localhost. Commented Jun 25, 2020 at 11:50

3 Answers 3

2

The problem is that you are returning a redirect on this get request, which is not allowed when using CORS.

I would definitely recommend looking at the MDN documentation if you're having troubles with such things, they're very useful and pretty near complete.

To fix this, you could return a payload with the correct auth url and follow that using your front end code.

I don't specifically know angular but I would imagine it would look something like:

googleLogin(){
  // This header options was not doing anything, the request cannot tell the server how to do CORS.
  const authUrl = this.http.get("https://localhost:44340/api/auth/googlelogin");
  return this.http.get(authUrl);
}
Sign up to request clarification or add additional context in comments.

11 Comments

If i dont use header options I get another error: ... has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
And in angular it is impossible to write return this.http.get(authUrl);, I can only return authUrl;.
Apparently Angular calls CORS automatically, so the header should definitely do nothing. Your WithOrigins function on the builder may be overriding your AllowsAnyOrigin which may be causing an issue. Maybe try with a normal payload first and go from there. The redirect may be throwing out red herrings.
What do u mean by normal payload first?
You can POST without a body, since this is an endpoint that does a change of state (logging in) you will want to use POST, since GET is meant to be for getting information and not changing state. If you change the Angular to .post and the method to [HttpPost()] it will now be a post method... As for the redirect, returning a payload with the url is still probably your best option, then you can follow it using angular and the CORS redirect issue will not exist.
|
2

When you make your ajax call to your backend and it returns a redirect to Google, your initial request will follow that redirect. This means you are trying to make an ajax call to Google, which is not allowed.

In order to solve this issue, you need to make an actual, full "postback" to your backend, either by some form submission or doing a window.location='yourdomain.page/path'. This is why is works when you drop the url in your browser and press Enter.

My suggestion is to have and endpoint that just returns the google oauth url that you can hit with ajax, then do a redirect i.e.

const url = await httpClient.get<GoogleAuth>('/oauth/google').toPromise(); //replace with your google auth returning endpoint
window.location = url;

2 Comments

What is <GoogleAuth>? Angular does not have such thing
That is just an example class, replace it with whatever your endpoint returns and can deserialize to.
0

To invoke ASP.NET Core built-in authentication flow from React or Angular frontend without running into CORS errors, you need to make the call to the backend API via a form submit. For example, you can wrap the login button in a form in the frontend as shown below (I'm using React but the same principle applies in Angular):

<form method='POST' action='https://localhost:44340/api/auth/googlelogin'>
    <Button type='submit'>
        Google Login
    </Button>
</form>

You'll also need to change the GoogleLogin method in your API to an HttpPost.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.