WoJ
WoJ

Reputation: 29987

How to handle CORS in a service account call to Google oAuth?

I access a Google calendar using a service account. This means that the owner of the calendar will not be prompted for his authorization.

This works fine in Python, where I make a requests call to https://accounts.google.com/o/oauth2/token with a specific body. This gets me back a token I can use later.

I now need to have an application running in a standalone browser (Chrome - without user interaction) and tried to directly port this call as

fetch('https://accounts.google.com/o/oauth2/token',
    {
        method: 'POST',
        body: JSON.stringify(body),
    })
    .then(function(res) { return res.json(); })
    .then(function(data) { alert(JSON.stringify(data)) })

but I get a reply from Google

Failed to load https://accounts.google.com/o/oauth2/token: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://devd.io' is therefore not allowed access. The response had HTTP status code 400. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.

My limited understanding of CORS (a previous answer was a very good read) is that

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

means that it is not present in the response headers, which means that Google does not want me to access its resources via JS when ran from the browser (which points to something else that https://accounts.google.com).

This may be a good idea but I control all elements, from the code to the browser and would like to get that token the same way I get it in a non-browser environment, specifically my working Python code.

How can I tell https://accounts.google.com to send me back a Access-Control-Allow-Origin header which tell my browser that it is OK to accept the call?

Upvotes: 2

Views: 4743

Answers (2)

WoJ
WoJ

Reputation: 29987

@Quentin's answer "You can't" is the right one for my question ("how can I force the server to send back the right header").

This is a decision at Google not to provide this header, effectively cutting off any non-interactive applications.

As a solution, I will look at

  • how to force the browser not to take into account the security mechanisms provided by CORS (there seems to be some ways through extensions or command-line arguments, I will update this answer once I find it)
  • or write an intermediate layer which will query the data for me and pass them verbatim to the application (this is equivalent, in my case, of just making the query from JS - but it adds an extra layer of code and server)

Upvotes: 1

Quentin
Quentin

Reputation: 943571

You can't.

Client side and server side code need to interact with OAuth in different ways.

Google provide documentation explaining the client side process.

Importantly, part of it involves redirecting to Google's servers instead of accessing them with fetch or XMLHttpRequest.

Upvotes: 5

Related Questions