Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

undefined is not an object (evaluating 'window.location.protocol') - React Native #345

Closed
jdnichollsc opened this issue Mar 4, 2020 · 22 comments
Labels

Comments

@jdnichollsc
Copy link

Hello guys,

As we can see here, @okta/okta-auth-js is a dependecy used from React Native too and we're using this workflow to have a custom native UI to authenticate the users.
With the latest version of @okta/okta-auth-js we're having this error:

React Native Okta

Any help is really appreciated! 👍

@aarongranick-okta
Copy link
Contributor

Hi @jdnichollsc,

Thanks for the report. okta-auth-js is designed to run in a browser, but apparently it can (or did) work within a native context as well. Can you try running with version 2.8.0 (the version specified by the react-native sample)?

@Pernett98
Copy link

Hi @aarongranick-okta we were using this version 2.11.2 and it works. But yesterday we realized about this issue with the last version.

@mscott-nimbly
Copy link

We're having the same issue trying to upgrade from 2.11.0. This was the library recommended to us by the Okta engineers so I really hope this gets resolved.

@swiftone
Copy link
Contributor

swiftone commented Mar 5, 2020

@mscott-nimbly - For context, are you running this with react-native as well?

@mscott-nimbly
Copy link

@mscott-nimbly - For context, are you running this with react-native as well?

Yes, react native 0.61.5

@BologaMarius
Copy link

I have the same issue with the latest version, I had to downgrade to 2.11 to make it work

@swiftone
Copy link
Contributor

swiftone commented Mar 6, 2020

Internal ref: OKTA-282531 and OKTA-282533

@swiftone swiftone added the bug label Mar 6, 2020
@swiftone
Copy link
Contributor

swiftone commented Mar 6, 2020

Thank you for the reports - at this time we can confirm that you should downgrade to okta-auth-js 2.11.x to retain react-native capability until we are able to address the problem.

Edit: The advice below to to use 3.x and set 'pkce: false' is also valid

@mnorste
Copy link

mnorste commented Mar 18, 2020

@swiftone

I am also using okta-auth-js in a react native app (at the suggestion of Okta support people) so that I can use my own sign in UI.
I use the react native library to trade the session token for an access token, but get the session token with okta-auth-js.

I tried upgrading to 3.0 to stay current and then ran into an issue in react native trying to use authClient.signIn:

"The current page is not being served with the HTTPS protocol.
For security reasons, we strongly recommend using HTTPS.
If you cannot use HTTPS, set "cookies.secure" option to false."

I updated my config to set cookies.secure: false and it works but I am worried about this option because the docs mention: Setting to false will allow setting cookies on an HTTP origin, but is not recommended for production applications.

Do you know why I am seeing this error on mobile and if setting cookies.secure: false is a safe fix or if there is a better solution?

@mnorste
Copy link

mnorste commented Mar 18, 2020

I did some digging through the code. The error I mentioned about appears only when I have remote debugging on the react-native app. Without remote debugging I get the same undefined error as the OP.

This is why:
in browser.js

  if (cookieSettings.secure && !sdk.features.isHTTPS()) {
    throw new AuthSdkError(
      'The current page is not being served with the HTTPS protocol.\n' +
      'For security reasons, we strongly recommend using HTTPS.\n' +
      'If you cannot use HTTPS, set "cookies.secure" option to false.'
    );
  }

isHTTPS implementation:

proto.features.isHTTPS = function() {
  return window.location.protocol === 'https:';
};

So a fix to this for people who want to use version 3.0+ is to either set cookies: { secure: false } in your config passed to the okta-auth-js client constructor.
Alternatively you could define window.location.protocol to https but setting cookies.secure is easier.

This library can't use the tokenManager to set cookies in react native anyway so I don't believe there is a security risk.

@aarongranick-okta
Copy link
Contributor

@m-stern "This library can't use the tokenManager to set cookies in react native anyway so I don't believe there is a security risk."

This is correct. okta-auth-js is primarily designed to run in a browser. If you are loading it within an embedded web view, then it is running in a browser. However if it is included directly in a react-native application, it is running within a native context and there will be no cookies. We will put in better handling for react-native in a future release, and then you will not see these warnings/errors.

@ShawnRoller
Copy link

My organization is also in need of this fix. We were using okta-auth-js 3.0.0 and ran into issues when running on a real iOS device (vs the simulator). We also noticed that if debug mode is turned off in the simulator, we get the same error:
undefined is not an object (evaluating 'window.location.protocol')

We are hoping this gets fixed soon as we have a react-native-web application, and had to undergo a downgrade for the web application to support the older 2.11 version of this SDK, which contains many breaking changes vs 3.0.

@mnorste
Copy link

mnorste commented Apr 2, 2020

@offensivelybad The differences you are seeing are because the debugger makes your JS run in a browser environment instead of react native so window.location.protocol is defined.

If you look through the source code for okta-auth-js it only checks window.location.protocol if cookies.secure is true. If you are using this in react-native, then you can't even use cookies so set that to false.

Also, I had to do this: window.location = { ...window.location, hostname: 'localhost' } before creating the auth client in order to suppress another error.
It is very hacky but it makes this library work enough to get a session token in react-native. Setting the hostname to localhost lets you avoid some of the security checks that the okta auth client makes on initialization.

@ShawnRoller
Copy link

@m-stern thanks for the help, however I'm still getting the same error. Here's my config, with private data obfuscated:

OKTA: {
  issuer: 'https://{myoktaorg}.okta.com',
  clientId: "{myclientid}",
  redirectUri: 'http://localhost:3000/index.html',
  endSessionRedirectUri: "http://localhost:3000/index.html",
  discoveryUri: 'https://{myoktaorg}.okta.com',
  scopes: ["openid", "profile", "offline_access"],
  requireHardwareBackedKeyStore: true,
  tokenManager: {
    autoRenew: true,
    storage: 'localStorage',
  },
  cookies: {
    secure: false
  }
}

@mnorste
Copy link

mnorste commented Apr 2, 2020

@offensivelybad I suggest looking at this file: https://github.com/okta/okta-auth-js/blob/1b317b64e0cfa1f64df46b76f16b9322617cb029/packages/okta-auth-js/lib/browser/browser.js

And searching for the error message you are seeing. The source code is pretty easy to follow. There is likely a check in there that is happening that you can prevent by changing a setting or by setting properties on window directly. It's hacky but it will make it work.

I am guessing that it is the block at line 74 in that browser.js file that is causing your error.

  if (this.options.pkce && !sdk.features.isPKCESupported()) {
    var errorMessage = 'PKCE requires a modern browser with encryption support running in a secure context.';
    if (!sdk.features.isHTTPS()) {
      errorMessage += '\nThe current page is not being served with HTTPS protocol. Try using HTTPS.';
    }
    if (!sdk.features.hasTextEncoder()) {
      errorMessage += '\n"TextEncoder" is not defined. You may need a polyfill/shim for this browser.';
    }
    throw new AuthSdkError(errorMessage);
  }

The easiest way to get rid of the error is to set pkce: false.

This will affect your security though if you are trying to run this in a web browser. I was using this library for a react-native mobile app and using it with Okta's oidcjs react native library as well.
(https://github.com/okta/okta-oidc-js/tree/master/packages/okta-react-native)

I had PKCE on in that library.

@anilpai
Copy link

anilpai commented Apr 17, 2020

cookies: {
    secure: false
  }

this works !

If the issue persists, try clearing the browser cookies.

@jdnichollsc
Copy link
Author

jdnichollsc commented Apr 17, 2020

But we don't have cookies from React Native, only from WebView

@swiftone
Copy link
Contributor

@jdnichollsc - we're trying out #363 to see if it addresses your issue - stay tuned.

@jdnichollsc
Copy link
Author

I sent a pull request after checking the last changes, thanks for your help! okta/okta-oidc-js#761

@swiftone
Copy link
Contributor

swiftone commented May 1, 2020

Closing this ticket as the original issue should be resolved with the latest version of okta-react-native.

Will follow up on okta/okta-oidc-js/issues/761 in that issue.

@swiftone swiftone closed this as completed May 1, 2020
@jdnichollsc
Copy link
Author

It's working very well, thanks for your help!

@CHANDRU-WMH
Copy link

@m-stern thanks for the help, however I'm still getting the same error. Here's my config, with private data obfuscated:

OKTA: {
  issuer: 'https://{myoktaorg}.okta.com',
  clientId: "{myclientid}",
  redirectUri: 'http://localhost:3000/index.html',
  endSessionRedirectUri: "http://localhost:3000/index.html",
  discoveryUri: 'https://{myoktaorg}.okta.com',
  scopes: ["openid", "profile", "offline_access"],
  requireHardwareBackedKeyStore: true,
  tokenManager: {
    autoRenew: true,
    storage: 'localStorage',
  },
  cookies: {
    secure: false
  }
}

Did you find any fix

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

10 participants