auth0 / auth0.js

Auth0 headless browser sdk
MIT License
989 stars 492 forks source link

Safari produces invalid_token error on login #894

Closed beno closed 5 years ago

beno commented 5 years ago

https://carnext.cloud People on Safari can not login there. Auth0 gives back an error:

{error: "invalid_token", errorDescription: "Request has been terminated Possible causes: the network is offline, Origin is not allowed by Access-Control-Allow-Origin, the page is being unloaded, etc."}

This is the code that gets run on the client. On Chrome it all works flawlessly.

class Auth
  constructor: ()->
    @auth0 = new auth0.WebAuth
      domain: 'xxx.eu.auth0.com',
      clientID: 'xxxxxx',
      responseType: 'token id_token',
      scope: 'openid profile',
      redirectUri: window.location.origin

authenticate: ->
   @auth0.authorize()

Happens on both auth0-js 9.8.2 & 9.9.0

Safari 12.0.2, Mac 0.14.2 (

Make sure to include as much information as possible for us to understand and reproduce the bug, that way we can fix it as quickly as possible.

luisrudge commented 5 years ago

This URL is returning a 404 for me. The error your mentioned is a network error. Are you using any extensions etc?

beno commented 5 years ago

Hi, thanks for your reply, yes we were making some changes, back up now.

I initially slightly misrepresented the issue (I overlooked that we are suppressing the console message ourselves), but on GitHub it is now accurately worded.

I have seen quite a bit of similar discussions, and am now under the impression we need (paid) Custom Domains turned on to make this work reliably in Safari?

Thanks for your help, Michel

On 17 Jan 2019, at 14:40, Luís Rudge notifications@github.com wrote:

This URL is returning a 404 for me. The error your mentioned is a network error. Are you using any extensions etc?

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/auth0/auth0.js/issues/894#issuecomment-455175204, or mute the thread https://github.com/notifications/unsubscribe-auth/AAC0o3hYGmFUHhr_hww6H8dQDUpxciQaks5vEH0-gaJpZM4aEq2u.

luisrudge commented 5 years ago

Safari only has issues when you want to refresh a token (silent authentication) because that runs on an iframe. Standard authentication should work correctly.

You'll want custom domains if you want to refresh a token from your website (to extend a session, for example).

In any case, since this is not an SDK issue, please contact support at https://support.auth0.com with a HAR file so they can better assist you.

beno commented 5 years ago

I can't really say what kind of issue it is, but on the support site it has been suggested to continue the discussion here. This is a huge problem for us and I have no idea how to fix it. Please help.

luisrudge commented 5 years ago

Can you send me the HAR File?

Luís


De: beno notifications@github.com Enviado: quinta-feira, janeiro 17, 2019 12:26 PM Para: auth0/auth0.js Cc: Luís Rudge; State change Assunto: Re: [auth0/auth0.js] Safari produces invalid_token error on login (#894)

I can't really say what kind of issue it is, but on the support site it has been suggested to continue the discussion here. This is a huge problem for us and I have no idea how to fix it. Please help.

— You are receiving this because you modified the open/close state. Reply to this email directly, view it on GitHubhttps://eur02.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Fauth0%2Fauth0.js%2Fissues%2F894%23issuecomment-455189920&data=02%7C01%7C%7Cbc185ed6c035450e26c908d67c87d3ce%7C84df9e7fe9f640afb435aaaaaaaaaaaa%7C1%7C0%7C636833320141443918&sdata=wS%2Blqpmhp3Fgi16Ekym7oC%2F0MP6%2FRj1vv5IcmrT1hrw%3D&reserved=0, or mute the threadhttps://eur02.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Fnotifications%2Funsubscribe-auth%2FAA5cE1UUZyB7-lpvncY9U5GHGfJACy6Tks5vEIgsgaJpZM4aEq2u&data=02%7C01%7C%7Cbc185ed6c035450e26c908d67c87d3ce%7C84df9e7fe9f640afb435aaaaaaaaaaaa%7C1%7C0%7C636833320141443918&sdata=Ghcf2ZuCWP2ujJn2nwfW1%2FsV0eAqcc1aOuByr3nQp1Y%3D&reserved=0.

beno commented 5 years ago

I am not familiar with HAR, but investigating it a bit tells me Safari can't do that? Has this changed? Either way, I can send you some code that shows the bug. BTW, I get it in development too, so it doesn't look like a https thing?

luisrudge commented 5 years ago

We have a doc explaining how to generate har files: https://auth0.com/docs/troubleshoot/har

beno commented 5 years ago

Great, it is In your mail

luisrudge commented 5 years ago

Did you check the Preserve Log checkbox? I’m only seeing a subset of requests. I need you to record the HAR file from the moment you hit carnext.cloud until auth0 redirects you back to your application.

I tested this myself and I'm seeing this request is failing: image

https://carnext-3p.eu.auth0.com/.well-known/jwks.json

That's why you're getting this error.

beno commented 5 years ago

Well I can’t open the inspector on an new private window, so the Recording is from when I click the login button until the error. I haven’t made any client changes or set any other policies. I can login with the same Safari browser just fine using the 01-Login example code, and we use nearly identical code.

BTW, the carnext.cloud app is not in production so feel free to play around with it and reproduce the error yourself.

I will retry the HAR recording later tonight.

Thanks, Michel

On 17 Jan 2019, at 17:38, Luís Rudge notifications@github.com wrote:

Did you check the Preserve Log checkbox? I’m only seeing a subset of requests. I need you to record the HAR file from the moment you hit carnext.cloud until auth0 redirects you back to your application.

I tested this myself and I'm seeing this request is failing:

https://carnext-3p.eu.auth0.com/.well-known/jwks.json

That's why you're getting this error.

Did you setup CORS in your client correctly? Maybe your policies are blocking this request in safari?

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub, or mute the thread.

luisrudge commented 5 years ago

The headers I just sent you come from your application. Those policies are blocking the jwks url and causing the parseHash method to fail.

image

beno commented 5 years ago

OK , thanks a lot, these are the defaults for an Elixir/Phoenix app so maybe something to address in the docs or error message?

I hate to take any more of your time, but could you point out which settings specifically are the culprit and what they should be?

In any case, thank you very much for your trouble and for pointing me in the right direction.

Brgds, Michel

On 17 Jan 2019, at 18:20, Luís Rudge notifications@github.com wrote:

The headers I just sent you come from your application. Those policies are blocking the jwks url and causing the parseHash method to fail.

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/auth0/auth0.js/issues/894#issuecomment-455255124, or mute the thread https://github.com/notifications/unsubscribe-auth/AAC0o9tfaTULH7wj031LfMjYVbis--GVks5vELDMgaJpZM4aEq2u.

luisrudge commented 5 years ago

There's nothing we can do in the SDK to prevent or improve the error message. The code can't differentiate between a failed request and a request that the Browser decided to block because of a policy.

I don't know how the policies work in general, but I'd say that cross-origin-window-policy and x-permitted-cross-domain-policies might be a good start. Also, if you use CNAME, this problem might go away entirely, since it wouldn't be a cross-origin request anymore.

beno commented 5 years ago

Well I removed all security headers from the response, but alas, the error remains. One very weird thing is that now every once in a while it does pass (after some reloads), but mostly it errors out exactly the same as before. What am I doing wrong. I put the unsecured config online so you can take a look.

And I was so sure we were there. This is really starting to wear me out.

On 17 Jan 2019, at 21:59, Luís Rudge notifications@github.com wrote:

There's nothing we can do in the SDK to prevent or improve the error message. The code can't differentiate between a failed request and a request that the Browser decided to block because of a policy.

I don't know how the policies work in general, but I'd say that cross-origin-window-policy and x-permitted-cross-domain-policies might be a good start. Also, if you use CNAME, this problem might go away entirely, since it wouldn't be a cross-origin request anymore.

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/auth0/auth0.js/issues/894#issuecomment-455329922, or mute the thread https://github.com/notifications/unsubscribe-auth/AAC0o5AoWqndR4uLRo9Xvwlvd3XhMOnoks5vEOQzgaJpZM4aEq2u.

luisrudge commented 5 years ago

I tested and got a weird redirect loop in chrome.. it only works in the second or third time. Safari never works..

I'm under the impression this is a server configuration issue, specially since you said the 01-login example works, but I can't pin point what it is. I sent a message to our backend team so they can figure this out.

I can login with the same Safari browser just fine using the 01-Login example code

Did you use the same tenant/client for this test?

beno commented 5 years ago

Yes all the same browsers on the same machine. Only difference is the server platform (node vs phoenix). I reverted some small experiments so the redirects etc should be back to normal.

On 18 Jan 2019, at 02:07, Luís Rudge notifications@github.com wrote:

I tested and got a weird redirect loop in chrome.. it only works in the second or third time. Safari never works..

I'm under the impression this is a server configuration issue, specially since you said the 01-login example works, but I can't pin point what it is. I sent a message to our backend team so they can figure this out.

I can login with the same Safari browser just fine using the 01-Login example code

Did you use the same tenant/client for this test?

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/auth0/auth0.js/issues/894#issuecomment-455390194, or mute the thread https://github.com/notifications/unsubscribe-auth/AAC0o_zIdsezIYE35h3EGBc0OHabbVL_ks5vER5HgaJpZM4aEq2u.

luisrudge commented 5 years ago

I wonder if the server is the issue? I never saw anything like this 😬 Can you write a quick repro using phoenix and put somewhere in github so I can clone and run it from my machine?

beno commented 5 years ago

It gets weirder and weirder, because when I do that and largely copy over the contents from 01-Login it all works fine (of course). So it is not Phoenix and those security headers are not the problem. So now I am thinking it is my Javascript-fu, since I made a slight rewrite and converted it to coffeescript. I will now move from the working code ( https://github.com/beno/auth0bug https://github.com/beno/auth0bug) to what produces the bug and see where it breaks. Sorry for calling it Auth0bug since it most likely is not that :)

On 18 Jan 2019, at 15:29, Luís Rudge notifications@github.com wrote:

I wonder if the server is the issue? I never saw anything like this 😬 Can you write a quick repro using phoenix and put somewhere in github so I can clone and run it from my machine?

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/auth0/auth0.js/issues/894#issuecomment-455564398, or mute the thread https://github.com/notifications/unsubscribe-auth/AAC0o6EYuo5fcOcnHcujP1epSPZSg1OFks5vEdpIgaJpZM4aEq2u.

beno commented 5 years ago

https://github.com/beno/auth0bug/commit/dfcd5acb454847177080f0c5b3e20d9b5b8c2371

This is what produces the error.

luisrudge commented 5 years ago

is this repo private? I'm getting a 404

beno commented 5 years ago

Welp how did that happen? Made it public now.

On 19 Jan 2019, at 02:44, Luís Rudge notifications@github.com wrote:

is this repo private? I'm getting a 404

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/auth0/auth0.js/issues/894#issuecomment-455737977, or mute the thread https://github.com/notifications/unsubscribe-auth/AAC0oxNCTlUToSjz42tiTh4TuZZ7KtyLks5vEnh3gaJpZM4aEq2u.

beno commented 5 years ago

So the gist of it is that I added these lines:

   handleAuthentication();
   if (isAuthenticated()) {
    // Start App...
   } else {
     webAuth.authorize();
   }

which gives the error, and I can get rid of it by adding a timeout.

   handleAuthentication();
   if (isAuthenticated()) {
    // Start App...
   } else {
    setTimeout(webAuth.authorize, 1000);
   }

This has got be the wildest bug hunt I have ever been on, but at least you have something to go on. I can't believe this has never happened before, I think my use case is pretty common? Also, I don't really understand why this timeout remedies anything, but it does. Anyway, thanks for your help and best of luck.

beno commented 5 years ago

Some more thoughts: it appears isAuthenticated needs a while to produce the correct answer? After login and handleAuthentication is called, isAuthenticated is still false, and this is where things start breaking down. I thought handleAuthentication was a normal, inline function, but it seems it has some network delay or something. Very strange, but I will implement it with callbacks so we get rid of this behaviour. Thanks again.

beno commented 5 years ago

@luisrudge Curious to hear your take on this?

luisrudge commented 5 years ago

Ops, sorry. I missed your last update. I'll come back to this today.

luisrudge commented 5 years ago

So, yeah... handleAuthentication is async because it calls parseHash, which is an async call and accepts a callback. In your case, the best way to handle this is add a callback to handleAuthentication.

handleAuthentication(function(err) {
  if (err || !isAuthenticated()) {
    webAuth.authorize();
  } else {
    console.log('Start App...');
  }
});
andreasvirkus commented 5 years ago

Note @beno that to make this work you should wrap webAuth.parseHash() in a Promise and resolve it in parseHash's callback, that way your code will know when handleAuthentication has finished.