添加链接
link管理
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接

So after reading through the posts here, I was finally able to make things work and want to pay it forward by laying out what I did.

Special thanks to @jannik as I use a lot of his code and ideas here. Also thanks to @dhruv2204 for guiding me in implementing Auth0 inside a background page.

I’m building a Popup Chrome Extension using React and use Auth0 for authentication/authorization.

Whilst I’m using react, I imagine the logic should work if you’re using something else. I’m not using any chrome-extension boilerplate and just use good old npx create-react-app .

It is also worth noting that I already have an existing webapp .

I used the auth0-react library . Initially, I was encountering problems wherein loginWithPopup would close my popup(extension) immediately after authorization. When I would reopen I would reopen the popup I’m already logged out so I really couldn’t login. The only thing that prevented this behavior was if the chrome devtools was open. (setting cacheLocation={'localStorage'} did not fix this which was @jannik ’s fix)

What I was finally able to do was:

Have my Sign In button just open up my webapp by calling
chrome.tabs.create({url: 'https://mywebapp.com/'})
Users can then just login there then reopen my popup extension afterwards.

Inside App.js I have this running to check authentication everytime someone opens the popup:

const getToken = async () => {
    try {
      const token = await getAccessTokenSilently()
     setToken(token)
    } catch (e) {
      console.log(e)
  useEffect(() => {
    getToken()
  }, [])

My logic for switching the ui for authenticated user is like this

const { isAuthenticated, getAccessTokenSilently, isLoading } = useAuth0()
const [authenticated, setAuthenticated] = useState(isAuthenticated)
useEffect(()=> {
    setAuthenticated(isAthenticated)
}, [isAuthenticated] )
return(
        { isLoading ? <LoadingPage /> : !authenticated ? <SignInPage /> : <HomePage /> }

The reason why we need to cast isAuthenticated from Auth0 to a custom authenticated state is because we need to manually setAuthenticated(false) on logout. @jannik explains the situation better here Sync auth state between multiple applications (SPA & Chrome Extension) - #21 by jannik

Finally, to Logout, this is what I do. This is basically straight from @jannik

const logoutHandler = () => {
    logoutHelper({ federated: true, returnTo: window.location.origin })
    fetch(`https://${auth0Domain}/v2/logout?federated=true&client_id=${auth0ClientId}`, {
      credentials: 'include',
      mode: 'no-cors'
    }).catch()
  const logoutHelper = (options) => {
    logout(options)
    setAuthenticated(false)
//some button in ui calls logoutHandler() onClick

Hope this helps. If you have suggestions please list it out here and just let me know. Thanks guys!

hey @lvillacin

thank you for sharing your effort! I came across exactly the same issues as you. In the last week, I started to use a more maintainable way. I’m using now the “Options” page of a chrome extension to manage the whole login and logout process:

In this way, I can use the normal login with popup and logout without any issues. Here is a little code fragment:

                                <Button
                                    id="loginButton"
                                    variant="contained"
                                    color="primary"
                                    onClick={loginWithPopup}
                                    {isAuthenticated ? 'Re-Authenticate' : 'Login'}
                                </Button>

The options page and the popup are sharing the same localstorage, that’s why that way works seamlessly.

My popup page is just showing a “settings” button, that is opening the options page in a new tab:
Screenshot 2021-04-20 at 11.58.59409×573 19.4 KB

Here is the code for the settings button:

                                        <Button
                                            id="loginButton"
                                            variant="contained"
                                            color="primary"
                                            onClick={() => chrome.tabs.create({
                                                url: `${window.location.origin}/options.html`,
                                            Start here
                                        </Button>

I like this solution the most, as you can just work with the official auth0 react library and things just work. The user-flow is a little different, but I think that is worth it.

hope that helps as well!! Getting auth0 work in a react chrome extension is a hell of a work!

Thanks @jannik I was actually thinking about doing this but didn’t push through since I’m just making the scaffolding and have not started working on the final UX.

I might try out having the options page too if our design requires it.

Are you using a boilerplate btw? If you are, can you share what boilerplate you’re using? Thanks!

I can highly recommend using the options page to manage auth0 login/logout.

And my boilerplate is this one: GitHub - lxieyang/chrome-extension-boilerplate-react: A Chrome Extensions boilerplate using React 18 and Webpack 5.
Working pretty good!

If you need to run Auth0 in Content Script or Background

Special thanks to @dhruv2204 for guiding me with this.

Use Manifest V2. Also Use @auth0/auth0-spa-js inside the background page and make the calls there.

The reason for this is because auth0 needs access to the DOM and background service workers (from manifest v3) do not have access to the DOM. Please not that manifest v2 will be deprecated soon. They just have not released an official deprecation date so for now this can work

Just use the chrome messaging API to call the the methods from content script if necessary. Doing this still works with the earlier mentioned methods.

Background.html

<script src="./background.js"></script>

Background.js:

import { Auth0Client } from '@auth0/auth0-spa-js'
const auth0 = new Auth0Client({
  domain: <YOUR_AUTH0_DOMAIN>,
  client_id: <YOUR_AUTH0_CLIENT_ID>,
  redirect_uri: <YOUR_CHROME_EXTENSION_URI> //chrome-extension:extensionid
const getToken = async () => {
  const token = await auth0.getTokenSilently()
  return token