16

I'm trying to implement google oauth2 authentication in my django app. I have followed all the steps as per the docs.

On the browser address bar,if I browser this https://foo.bar.net/api/v1/auth/login/google-oauth2/ this url, it properly authenticated by google and it returns a google-auth-token to the mentioned redirect-url and it fetches the auth-token and converts it to a normal token which then sends to the user or frontend in json format.

But if I tried to make a GET request to the above mentioned url from my js code, it shows

Reason: CORS header 'Access-Control-Allow-Origin' missing

Full traceback on the frontend looks like,

GET https://foo.bar.net/api/v1/auth/login/google-oauth2/ 302 Found 718ms    
polyfil...ndle.js (line 7507)
GET https://accounts.google.com/o/oauth2/auth?client_...DW&response_type=code&scope=openid+email+profile 200 OK
Login Failed Response { _body=Event error,  status=0,  ok=false,  more...}
main.bundle.js (line 367)
Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at https://accounts.google.com/o/oauth2/auth?client_id=kguygvh868697-khgkhvkgvkgkgv.apps.googleusercontent.com&redirect_uri=https://foo.bar.net/api/v1/auth/complete/google-oauth2/&state=Cbms1QhSQVzjO3xkjhkyuu&response_type=code&scope=openid+email+profile. (Reason: CORS header 'Access-Control-Allow-Origin' missing).

I have searched google which prompts me to install djang-CORS-headers. I have installed and configured the above package. But the same error appears.

A part of my settings.py looks like,

MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'corsheaders.middleware.CorsMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
    'oauth2_provider.middleware.OAuth2TokenMiddleware',
]

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'rest_framework',
    'oauth2_provider',
    'corsheaders',
    'rest_framework_swagger',
]

CORS_ORIGIN_ALLOW_ALL = True

Actually we have two separate projects for both frontend(ang) and backend(django). I'm agree with ajax issue. So that I made the google oauth url to get opened in a separate window.

In the backend, I have done upto getting the server access token and exchange it with our application's access token. Currently I'm returning the token details in json format. So this json would be displayed in the newly opened window. But don't know how to

  1. get the token from the window and store it to a temp storage on the browser.

  2. close the new window once the details got appeared.

  3. redirect to users/profile page by passing the token information in the request header.

Don't know whether this oauth flow is correct or not.. And also I don't want full oauth flow to be in the js part(oauth implicit flow). Pls guide me in the right direction.

Avinash Raj
  • 172,303
  • 28
  • 230
  • 274
  • You can't do the redirect to google in ajax. – charlietfl Sep 24 '17 at 07:11
  • @charlietfl yep, actually I'm doing the GET request through angular – Avinash Raj Sep 24 '17 at 07:12
  • *“Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at https://accounts.google.com/o/oauth2/auth?… (Reason: CORS header 'Access-Control-Allow-Origin' missing)”* indicates the problem isn’t because of lack of CORS support on your own server but instead because that Google endpoint very intentionally doesn’t support receiving requests (by XHR or the Fetch API) from frontend JavaScript code running in a browser. The fact that Access-Control-Allow-Origin response header is missing isn’t an oversight; the lack of it means “no cross-origin requests allowed” – sideshowbarker Sep 24 '17 at 07:13
  • 1
    Need to open in a new window and use some javascript in return url to communicate with opening window when oauth returns the token – charlietfl Sep 24 '17 at 07:14
  • Take a look at `hello.js` library for example – charlietfl Sep 24 '17 at 07:16
  • @sideshowbarker so the problem was only with the frontend code not with backend, right? – Avinash Raj Sep 24 '17 at 07:18
  • @AvinashRaj no ... is a whole workflow problem. – charlietfl Sep 24 '17 at 07:18
  • AvinashRaj: as @charlietfl alludes to, the problem is that the workflow you’re trying to use isn’t going to work at all. Google doesn’t support it, for good reasons. If you need to integrate with Google for authentication then you need to do it in a way they actually support — as outlined in their documentation – sideshowbarker Sep 24 '17 at 07:27
  • "then you need to do it in a way they actually support — as outlined in their documentation", any relevant docs for angular? – Avinash Raj Sep 24 '17 at 07:38
  • @sideshowbarker actually we have two seperate projects for both frontend(ang) and backend(django). In the backend, I have done upto getting the server access token and associate it with our application's access token. Now I have to login using the application's access token and then it should redirect me to the users/me page. I have created an API for users/me which should return json as response. But returning this json won't help. I have to redirect the response to a frontend url, but don't know how.. – Avinash Raj Sep 25 '17 at 09:43
  • Avinash Raj, see https://stackoverflow.com/questions/43276462/cors-issue-while-requesting-access-token-google-oauth-2/43276710#43276710 and https://stackoverflow.com/questions/43225969/spring-oauth2-cross-origin-solution/43226416#43226416 – sideshowbarker Sep 25 '17 at 10:15
  • Hi there. I dont understand why are you doing this using django rest framework. Feels like you are off the track. Did you look at google python oath library? https://developers.google.com/api-client-library/python/guide/aaa_oauth Or did you look at the suggeted workflows for doing this? https://developers.google.com/identity/protocols/OAuth2 – Alex Sep 30 '17 at 17:31

1 Answers1

8

The problem is the Authorization code flow should not be used in front end, you need to use implicit flow here (https://developers.google.com/actions/identity/oauth2-implicit-flow) instead of authorization code flow(https://developers.google.com/actions/identity/oauth2-code-flow)

I think you also have missed to mention the headers allowed

  CORS_ALLOW_HEADERS = (
    'accept',
    'accept-encoding',
    'authorization',
    'content-type',
    'dnt',
    'origin',
    'user-agent',
    'x-csrftoken',
    'x-requested-with',
)
RamiReddy P
  • 1,628
  • 1
  • 18
  • 29