Hi all! Thank you in advance for any insights! We...
# gooddata-cloud
k
Hi all! Thank you in advance for any insights! We are building a nextjs application so we can leverage GoodData.UI for embedded visualizations. Additionally, we are a fully white-labeled domain using Auth0 as our OIDC identity provider. Furthermore, Auth0 is also fully white-labeled using custom auth domains. We currently have the nextjs app and GD.Cloud using the same Auth0 application, but we are running into a weird situation. Basically, our users are logging-in to the nextjs successfully, but when they go to a page that contains GD.UI visualizations, it causes them to have to re-authenticate with Auth0 again, and then the visualizations come through properly based on our GoodData group permissions that we have setup. We are looking for a way to eliminate this double-auth because its causing some UX friction for our clients. I have a feeling it has to do with how we have
tiger
setup (see below). Is there another way to pass in the Auth0 access tokens to
tigerFactory
where we don't have to re-authenticate the user again.
Copy code
const backend = tigerFactory()
                  .onHostname("<https://dashboard.ourgooddatadomain.com>")
                  .withAuthentication(new ContextDeferredAuthProvider(redirectToTigerAuthentication));
We've tried to follow the blog post here but it doesn't make any reference to BackendProvider or WorkspaceProvider that is mentioned in the GD.UI SDK docs. Additionally, we've looked into integrating into an existing app here but still get the double-auth0 prompt. Is it something to do with cookie security?
m
Hello Kyle, I understand that you are using GoodData Cloud and want to eliminate the double authentication flow in your nextjs application. As a first step, would it be possible to get the contents of your package.json file and send us a snippet of your authentication implementation? If you are not comfortable sharing this in the thread, please feel free to send me the details via DM.
k
Copy code
{
  "name": "mini-outburst",
  "version": "0.1.0",
  "private": true,
  "scripts": {
    "dev": "next dev -H 0.0.0.0",
    "build": "next build",
    "start": "next start",
    "lint": "next lint",
    "pages:build": "npx @cloudflare/next-on-pages",
    "preview": "npm run pages:build && wrangler pages dev .vercel/output/static",
    "deploy": "npm run pages:build && wrangler pages deploy .vercel/output/static",
    "db:list": "npx wrangler d1 migrations list mini-outburst --local",
    "db:generate": "drizzle-kit generate:sqlite --schema=src/app/schema.ts",
    "db:migrate": "npx wrangler d1 migrations apply mini-outburst --local",
    "db:list:prod": "npx wrangler d1 migrations list mini-outburst",
    "db:migrate:prod": "npx wrangler d1 migrations apply mini-outburst",
    "debug": "NODE_OPTIONS='--inspect' next dev"
  },
  "dependencies": {
    "@auth0/auth0-react": "^2.2.4",
    "@fortawesome/fontawesome-svg-core": "^6.5.1",
    "@fortawesome/free-solid-svg-icons": "^6.5.1",
    "@fortawesome/react-fontawesome": "^0.2.0",
    "@gooddata/api-client-tiger": "^10.0.0",
    "@gooddata/sdk-backend-tiger": "^10.0.0",
    "@gooddata/sdk-ui-all": "^10.0.0",
    "drizzle-orm": "^0.29.4",
    "jose": "^5.2.4",
    "next": "^14.2.3",
    "react": "^18.2.0",
    "react-dom": "^18.2.0",
    "styled-components": "^6.1.11",
    "swr": "^2.2.5"
  },
  "devDependencies": {
    "@cloudflare/next-on-pages": "^1.9.0",
    "@cloudflare/workers-types": "^4.20240208.0",
    "@gooddata/catalog-export": "^10.0.0",
    "@types/node": "^18.17.0",
    "@types/react": "^18.2.0",
    "@types/react-dom": "^18.2.1",
    "autoprefixer": "^10.0.1",
    "drizzle-kit": "^0.20.14",
    "eslint": "^8",
    "eslint-config-next": "14.1.0",
    "eslint-plugin-next-on-pages": "^1.9.0",
    "postcss": "^8",
    "tailwindcss": "^3.3.0",
    "typescript": "^5",
    "vercel": "^33.5.1",
    "wrangler": "^3.28.4"
  }
}
Copy code
import tigerFactory, { ContextDeferredAuthProvider, redirectToTigerAuthentication } from "@gooddata/sdk-backend-tiger";

// or if your application will be hosted on a different host than the GoodData Cloud or <http://GoodData.CN|GoodData.CN> backend
const backend = tigerFactory()
                  .onHostname("<https://dashboard.outburstdata.com>")
                  .withAuthentication(new ContextDeferredAuthProvider(redirectToTigerAuthentication));

export default backend;
and then this is how we stack the providers
i've tried ordering them a bit differently to with GD
BackendProvider
under Auth0 and then modifying the
tigerFactory
to silently fetch an access token and use
TigerTokenAuthProvider
but that doesn't seem to work either
@Moises Morales thanks for the response. added some details above
r
Hi there Kyle, Radek from the GoodData Technical team here - the issue was passed over to us for checking, let's see where this is going wrong! 🙂
I think you're on the right path in trying to modify the backend setup; the issue you're having is that in the
ContextDeferredAuthProvider
, you're telling the app to solve auth via redirecting to the auth page essentially; instead, you need to be able to provide the auth context already established when the user previously logged in through NextJS. I'll try and give you somewhat more specific directions, but that about covers the theory at least!
k
@Radek Novacek awesome, thanks! i had a feeling it was related to the provider, but I wasn't really sure which/how to pass the
Auth0Provider
into the tiger factory
@Radek Novacek @Moises Morales any thoughts or updates here?
👀 1
r
Hey there @Kyle Schutt, apologies for the delay! I've also been trying to figure out how to pass the auth context properly, ended up having to check with the devs for the right approach - waiting for a reply at the moment, but I'll make sure to keep you updated as soon as I know more 🙂
k
@Radek Novacek appreciate it! fwiw, I tried nesting providers and inspecting the Auth0 implementation for GoodData, but couldn't figure out the correct order or how to re-use tokens
r
Have you come across the implementation of the
ContextDeferredAuthProvider
itself? the source code of the GD.UI SDK is available on GitHub, and the flow is described in this link here 🙂
k
i think i tried this one too, but i will try it again. I guess my issue is should i be using the same auth0 application for GD and our custom application so that they use the same auth0 keys?
r
That's the only way I can think of the login working seamlessly, otherwise I suspect you'd always end up with a login redirect from the GD side even after passing the existing auth. You can also always share the implementation attempt snippet here (or via messages) and I can get the devs to chime in on where it's going wrong 🙂
k
Copy code
import tigerFactory, { ContextDeferredAuthProvider, redirectToTigerAuthentication } from "@gooddata/sdk-backend-tiger";

// or if your application will be hosted on a different host than the GoodData Cloud or <http://GoodData.CN|GoodData.CN> backend
const backend = tigerFactory()
                  .onHostname("<https://dashboard.outburstdata.com>")
                  .withAuthentication(new ContextDeferredAuthProvider(redirectToTigerAuthentication));

export default backend;
this is what we are currently using. are you saying we should use something different from
redirectToTigerAuthentication
?
r
Definitely - the redirect function works as advertised, it will just redirect you to the auth page regardless of your actual auth status in the NextJS app!