auth0 / nextjs-auth0

Next.js SDK for signing in with Auth0
MIT License
2.05k stars 389 forks source link

Vercel Preview and Production Setup is daunting #566

Closed Mandalorian007 closed 2 years ago

Mandalorian007 commented 2 years ago

For some context I am a fairly new user of NextJs, Vercel and Auth0.

My current application is best described as a NextJS application leveraging @auth0/nextjs-auth0

Getting the application setup to correctly manage the local environment and the production environment with Vercel and Auth0 was extremely pleasant.

leveraging the prebuilt handleAuth api with a few environment variables did the trick.

// pages/api/auth/[...auth0].js
import {handleAuth} from "@auth0/nextjs-auth0";

export default handleAuth();

Using the local env file:

AUTH0_SECRET='{32 characters of fun}'
AUTH0_BASE_URL='http://localhost:3000'
AUTH0_ISSUER_BASE_URL='https://{AUTH0_ISSUER_DOMAIN}.auth0.com'
AUTH0_CLIENT_ID='{AUTH0_CLIENT_ID}'
AUTH0_CLIENT_SECRET='{AUTH0_CLIENT_SECRET}'

These environment variables were added to Vercel in all environments except for the AUTH0_BASE_URL which was set to be https://{MY_CUSTOM_DOMAIN}.com

In Auth0 I configured the callback and logout urls callbacks:

http://localhost:3000/api/auth/callback
https://{MY_CUSTOM_DOMAIN}.com/api/auth/callback

logout:

http://localhost:3000/
https://{MY_CUSTOM_DOMAIN}.com/

This experience was super smooth and worked like a charm.

The complexity exploded when I tried to make the preview environments function correctly.

The Auth0 setup was a breeze with the wildcard matching. callbacks:

https://{GIT_REPO_STUB}-*-{VERCEL_TEAM}.vercel.app/api/auth/callback

logout:

https://{GIT_REPO_STUB}-*-{VERCEL_TEAM}.vercel.app/

However, after some confusion occurred when setting the AUTH0_BASE_URL to the VERCEL_URL using the .env.production file. After lots of investigation I realized that the VERCEL_URL that was being set to the AUTH0_BASE_URL was incorrect. It looks like the VERCEL_URL when the build happened is not the same environment variable when the application was running in production.

I had my suspicion confirmed of this when reading this issue: https://github.com/auth0/nextjs-auth0/issues/420

However, I discovered from that issue that someone had created a custom override for the handleAuth. https://github.com/auth0/nextjs-auth0/issues/108#issuecomment-800059278

When leveraging this solution it indeed did get my preview environment and my local environment functioning correctly. However, this solution in production caused an issue since the url being resolved was the vercel production application URL (ex: https://{gitstub}-378kjmskg-{vercelteam}.vercel.app/) instead of the custom domain ( https://{MY_CUSTOM_DOMAIN}.com/ ) that was purchased for the website. As a note this solution does function using the production url generated by vercel.

At this point I am running out of ideas on how it's possible to configure Auth0 for Local, Preview, and Production (with custom domain). Ideally, it would be great to get a straightforward solution for this and some documentation to help reduce future user pain. Potentially, I have overlooked something simple so please feel free to point me in the right direction if that is the case.

adamjmcgrath commented 2 years ago

Hi @Mandalorian007 - thanks for raising this

Have a look at https://github.com/auth0/nextjs-auth0/tree/main/examples#production-deployments-or-other-environments-with-fixed-urls and let me know if this fixes your issue

Mandalorian007 commented 2 years ago

@adamjmcgrath I read that and it was very helpful for handing the production deployment of the application and it worked well. using .env.local to ensure the url would be http://localhost:3000 and then setting the production environment to be my custom domain https://{MY_CUSTOM_DOMAIN}.com worked perfectly.

The trouble I had with this approach came down to how Vercel creates preview environments. The URL isn't predictable (to the best of my knowledge). Going through Vercel's pre-defined environment variables (https://vercel.com/docs/concepts/projects/environment-variables#system-environment-variables) lead me to believe that I could use the VERCEL_URL, but after a bunch of testing I discovered that the VERCEL_URL in the Preview environment isn't the same host url as where the application is running. My guess is this is because NextJs applications have both server side lambdas, and the site url.

adamjmcgrath commented 2 years ago

Hi @Mandalorian007 - for preview deployments you want to set AUTH0_BASE_URL in .env.production, see https://github.com/auth0/nextjs-auth0/tree/main/examples#preview-deployments

You can either use the Automatic Deployment URL or Automatic Branch URL, but you can't do both (unless you do the workaround described in https://github.com/auth0/nextjs-auth0/issues/108#issuecomment-800059278)

Mandalorian007 commented 2 years ago

@adamjmcgrath Thank you for the feedback it's much appreciated. Been experimenting a bunch with the preview environment configuration and I still can't get it working correct.

Given the documentation it says: Automatic Branch URL: For example project-git-update-team.vercel.app which can be constructed using ${VERCEL_GIT_REPO_SLUG}-git-${VERCEL_GIT_COMMIT_REF}-${VERCEL_GIT_REPO_OWNER}.vercel.app

Given this information on Vercel I setup a custom environment variable for the Preview environment: image

Based on my current environment when my preview branch is deployed I received the url: https://vtt-adventure-packer-git-adjusttinymcetob-ce63bc-mandalorian007.vercel.app/

When I attempt to login with Auth0 on my preview environment I receive a callback url for: https://vtt-adventure-packer-git-adjust_tinymce_to_be_uncontrolled_component-mandalorian007.vercel.app/api/auth/callback?code=LONG_CODE_HERE&state=LONG_CODE_HERE

comparing the two urls I can see the difference:

https://vtt-adventure-packer-git-adjusttinymcetob-ce63bc-mandalorian007.vercel.app/
https://{GIT_REPO_SLUG}-git-{GIT_COMMIT_REF}-{GIT_REPO_OWNER}

vs:

https://vtt-adventure-packer-git-adjust_tinymce_to_be_uncontrolled_component-mandalorian007.vercel.app/
https://{GIT_REPO_SLUG}-git-{GIT_BRANCH_NAME}-{GIT_REPO_OWNER}

Based on the Vercel Environment Variable documentation: image

It appears as if GIT_COMMIT_REF populated by Vercel is using the branch name while the Preview Environment in Vercel is using part of the commit number or something else: commit number: d0df6d85a7e0796ccac15d106f310965768ce87c generated url part: ce63bc

It does appear like the full commit sha is available in their environment variable documentation, but I don't think I could use a substring function in the Vercel UI while assigning an environment variable image

Hopefully, this context was detailed enough. If not I can try and get additional information

adamjmcgrath commented 2 years ago

Hi @Mandalorian007

Based on my current environment when my preview branch is deployed I received the url

When you deploy to Vercel, you should receive 2 (or more) urls

image

One of them should be the "Automatic Branch URL", which should follow the pattern ${VERCEL_GIT_REPO_SLUG}-${VERCEL_GIT_COMMIT_REF}-${VERCEL_GIT_REPO_OWNER}.vercel.app

Have just tested this with the following branch: https://github.com/adamjmcgrath/vercel-deploy-test-app/blob/adamjmcgrath-patch-1

Which has the following .env.production set https://github.com/adamjmcgrath/vercel-deploy-test-app/blob/adamjmcgrath-patch-1/.env.production#L1

Which generates the following callback url as expected https://vercel-deploy-test-app-adamjmcgrath-patch-1-adamjmcgrath.vercel.app/api/auth/callback

Mandalorian007 commented 2 years ago

@adamjmcgrath It took a bit of testing, but I got it working!

Swapping to the .env.production file and removing my preview environment variables. I first started with the same configuration as yours above. https://github.com/adamjmcgrath/vercel-deploy-test-app/blob/adamjmcgrath-patch-1/.env.production#L1

However, after a few attempts with not finding the site I realized that my application was actually deploying with git in the url name. So I added git into the .env.production file:

AUTH0_BASE_URL=${VERCEL_GIT_REPO_SLUG}-git-${VERCEL_GIT_COMMIT_REF}-${VERCEL_GIT_REPO_OWNER}.vercel.app

image

After this change I noticed that the redirect seemed to be coming to the correct domain this time and I was able to successfully login.

One thing I am not quite certain on is that in your example above when you hover over the multiple urls your app is deployed to I can see that your url also looks like it has the git part in the url, but you seem to be having success without that in that in your .env.production file. I am not quite sure what the difference is between our two cases.

adamjmcgrath commented 2 years ago

Hi @Mandalorian007

One thing I am not quite certain on is that in your example above when you hover over the multiple urls your app is deployed to I can see that your url also looks like it has the git part in the url, but you seem to be having success without that in that in your .env.production file. I am not quite sure what the difference is between our two cases.

Yep, good point. That .env.production file should have -git- in it, I never actually hooked it up (just tested with the Callback URL mismatch error) - but if I did I would have got a 404 on my callback.

The example app in the repo's .env.production is correctly configured with the -git- bit

Mandalorian007 commented 2 years ago

@adamjmcgrath Thank you for your time and assistance in debugging this. It is greatly appreciated ❤️.

Circling back to the docs and reading them now it is clear that they are definitely correct and I had some miss understandings around the concepts of Automatic Deployment URLs vs Automatic Branch URLs. I believe that since it was my first time using Vercel and the Github integration abstracting some of the deployment information left me a bit lost.

A recommendation for the docs to help newer users could be to provide a link to Vercel's Automatic URL documentation from the example's preview deployment documentation.

adamjmcgrath commented 2 years ago

No problem @Mandalorian007 - glad you got it working

A recommendation for the docs to help newer users could be to provide a link to Vercel's Automatic URL documentation from the example's preview deployment documentation.

Good idea, have raised #576

cbovis commented 2 years ago

@adamjmcgrath it's worth pointing out that this solution isn't bullet proof because of URL truncation: https://vercel.com/docs/concepts/deployments/generated-urls#truncation.

I've reached out to Vercel support to see if they have any tips around making this easier. Ideally they'd provide an additional type of VERCEL_URL variable which actually reflects the domain being viewed. Will report back if I have any luck.