{"id":24935174,"url":"https://github.com/midoru0121/nextjs-auth0-supabase-integration-example","last_synced_at":"2026-04-19T19:32:15.822Z","repository":{"id":275135390,"uuid":"922840552","full_name":"midoru0121/nextjs-auth0-supabase-integration-example","owner":"midoru0121","description":"Auth0 and Supabase Integration Example with Next.js","archived":false,"fork":false,"pushed_at":"2025-02-03T13:24:26.000Z","size":110,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-10-17T10:54:37.523Z","etag":null,"topics":["auth0","nextjs","supabase"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/midoru0121.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2025-01-27T07:06:45.000Z","updated_at":"2025-06-19T08:50:07.000Z","dependencies_parsed_at":"2025-02-02T08:18:38.881Z","dependency_job_id":"64230079-6083-44fa-9682-323faa383f88","html_url":"https://github.com/midoru0121/nextjs-auth0-supabase-integration-example","commit_stats":null,"previous_names":["midoru0121/auth0-supabase-integration-example","midoru0121/nextjs-auth0-supabase-integration-example"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/midoru0121/nextjs-auth0-supabase-integration-example","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/midoru0121%2Fnextjs-auth0-supabase-integration-example","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/midoru0121%2Fnextjs-auth0-supabase-integration-example/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/midoru0121%2Fnextjs-auth0-supabase-integration-example/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/midoru0121%2Fnextjs-auth0-supabase-integration-example/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/midoru0121","download_url":"https://codeload.github.com/midoru0121/nextjs-auth0-supabase-integration-example/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/midoru0121%2Fnextjs-auth0-supabase-integration-example/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32020501,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-18T20:23:30.271Z","status":"online","status_checked_at":"2026-04-19T02:00:07.110Z","response_time":55,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["auth0","nextjs","supabase"],"created_at":"2025-02-02T15:21:44.282Z","updated_at":"2026-04-19T19:32:15.803Z","avatar_url":"https://github.com/midoru0121.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"[日本語](https://github.com/midoru0121/auth0-supabase-integration-example/blob/main/README_ja.md)\n\n# nextjs-auth0-supabase-integration-example\n\nThis is the flow of the application. Assumption: The signing algorithm for both Supabase and Auth0 is set to `RS256`.\n\n- Authenticate the user using Auth0.\n- Immediately after logging in via Auth0, assign the role previously created in Auth0 to the user.\n- Include the above role in the payload, sign it with Supabase’s JWT secret, and store it in the @auth0/nextjs-auth0 session.\n  - From here on, it can be accessed as a session inside Next.js’s RSC. This JWT will be used as an access token for Supabase.\n- Access Supabase from within Next.js’s RSC (when doing this, attach the above access token as a Bearer token in the request).\n- On the Supabase side, decode the JWT for the RLS policy and check if the role is included.\n  - If the role is not included, deny access to the table.\n  - If the role is included, grant access to the table.\n\n## Setting Up Auth0\n\n### Creating an Auth0 Application\n\nAfter registering with Auth0, create an application and select `Regular Web Applications`.\n\nClick `Settings` to navigate to the configuration page.\n\n![Image](https://github.com/user-attachments/assets/06465bbf-7b3a-4334-836e-c9bf1bc054cd)\n\nNote down `Domain`, `Client Id`, and `Client Secret`, as they will be needed later.\n\n![Image](https://github.com/user-attachments/assets/05f17c99-4447-46a3-9816-57333af1aafb)\n\nSet `Allowed Callback URLs` to `http://localhost:3000/api/auth/callback`.\nSet `Allowed Logout URLs` to `http://localhost:3000`.\n\n![Image](https://github.com/user-attachments/assets/644b5421-12aa-4583-853f-28940824ff17)\n\nThen, set `OAuth` and `JSON Web Token Signature` to `RS256`. Also, check that the `OIDC Conformant` box is checked.\n\n![Image](https://github.com/user-attachments/assets/59f1898e-18ef-47cc-a173-9b0ed2b6c803)\n\nGo to `Connections` and enable `google-oauth-2` to allow sign-ups via Google accounts.\n\n![googleOAuthConnection](https://github.com/user-attachments/assets/28683d31-91ee-4f2b-a41e-75044644a713)\n\n### Configuring the Auth0 Management API\n\nSelect the Auth0 Management API, choose `Machine to Machine Applications`, and check the `Authorized` button. Then, expand the details.\n\n![MachineToMachineApplications](https://github.com/user-attachments/assets/20cfbfd0-c189-444e-9cd8-fc492f2c7149)\n\n![SelectAuth0ManagementAPI](https://github.com/user-attachments/assets/91b68db3-4d99-4cca-8628-40c67225a69d)\n\nAdd the following permissions: `read:users`, `update:users`, and `read:roles`.\n\n![permissions](https://github.com/user-attachments/assets/0761dd70-b93b-401f-8bed-b08aabe6bfce)\n\n### Creating a Role\n\nClick `Roles` and create an `Authenticated` role. This role will be assigned to users by default.\n\n![IcreateRole1](https://github.com/user-attachments/assets/516318f3-3ff7-4528-9b0b-c0bf3f375cd3)\n\n![IcreateRole2](https://github.com/user-attachments/assets/31872540-82d5-4527-b526-af33a1f21b00)\n\nNote the `Role ID` of the `Authenticated` role, as it will be used later.\n\n![createRole3](https://github.com/user-attachments/assets/15639ae2-9c48-41ce-90b3-11e3fdcd74d6)\n\n## Setting Up Auth0 Post Login Action\n\nTo assign a default role upon user login, set up a `Post Login Action`.\n\nGo to `Actions` \u003e `Triggers` and click `post-login`.\n\n![CreateAction](https://github.com/user-attachments/assets/6ad9758a-3601-4017-be23-1f6126e0e2a1)\n\nSelect `Build from scratch`.\n\n![CreateAction2](https://github.com/user-attachments/assets/af677761-be0a-4d67-8104-6957e3fab4fc)\n\nName the action and click `Create`.\n\n![CreateAction3](https://github.com/user-attachments/assets/7809b2d4-755f-4c4d-ac36-01a10d02726a)\n\nGo to `Secrets` and add `DOMAIN`, `CLIENT_SECRET`, `CLIENT_ID`, and `DEFAULT_ROLE_ID`.\n\n![CreateAction5](https://github.com/user-attachments/assets/c4ff31d2-a28e-48ba-ae40-3548cbb39898)\n\nClick `Add Dependency` and add `auth0` and `axios`.\n\n![createAction8](https://github.com/user-attachments/assets/cd519d3d-4e29-4f06-9456-accbc80fe118)\n\nPaste the following code:\n\n```javascript\nexports.onExecutePostLogin = async (event, api) =\u003e {\n  // Import Axios\n\n  const axios = require(\"axios\").default;\n\n  // Import Auth0 Management API client\n\n  const { ManagementClient } = require(\"auth0\");\n\n  // Define a namespace for custom claims\n  const roleNamespace = \"https://auth0-supabase-interation-example.com/roles\";\n\n  // If the user already has roles, exit the process\n  if (\n    event.authorization \u0026\u0026\n    event.authorization.roles \u0026\u0026\n    event.authorization.roles.length \u003e 0\n  ) {\n    console.log(\"The user has roles.\");\n    // Set existing roles as custom claims\n    const roles = event.authorization.roles.join(\",\");\n    api.idToken.setCustomClaim(roleNamespace, roles);\n\n    return;\n  }\n\n  try {\n    // Get the access token for the Management API\n    const options = {\n      method: \"POST\",\n      url: `https://${event.secrets.DOMAIN}/oauth/token`,\n      headers: {\n        \"Content-Type\": \"application/x-www-form-urlencoded\",\n      },\n      data: new URLSearchParams({\n        grant_type: \"client_credentials\",\n        client_id: event.secrets.CLIENT_ID,\n        client_secret: event.secrets.CLIENT_SECRET,\n        audience: `https://${event.secrets.DOMAIN}/api/v2/`,\n        scope: \"read:roles update:users\",\n      }),\n    };\n\n    const response = await axios.request(options);\n\n    // Initialize the Management API client\n    const management = new ManagementClient({\n      domain: event.secrets.DOMAIN,\n      token: response.data.access_token,\n    });\n\n    // Assign roles to the user\n    const params = { id: event.user.user_id };\n    const data = { roles: [event.secrets.DEFAULT_ROLE_ID] };\n\n    await management.users.assignRoles(params, data);\n\n    // Get role details from the API\n    const roleResponse = await axios.get(\n      `https://${event.secrets.DOMAIN}/api/v2/roles/${event.secrets.DEFAULT_ROLE_ID}`,\n      {\n        headers: {\n          Authorization: `Bearer ${response.data.access_token}`,\n        },\n      }\n    );\n    // Set the role name of the user as a custom claim in the ID token\n    api.idToken.setCustomClaim(roleNamespace, roleResponse.data.name);\n\n    console.log(\"Success\");\n  } catch (e) {\n    // Log the error\n    console.log(e);\n  }\n};\n```\n\nClick `Deploy`.\n\n![CreateAction4](https://github.com/user-attachments/assets/e2082079-6b8c-48df-a2e1-4c458687fb9d)\n\nReturn to the `post-login` configuration and place the deployed action right after `User Logged In`.\n\n![createAction7](https://github.com/user-attachments/assets/eb3e4872-4f25-4169-8902-8c2a16b8a79c)\n\n## Creating a Supabase Project\n\nAfter registering with Supabase, go to `Settings -\u003e API` and note the `Project URL`, `anon key`, and `JWT_SECRET`.\n\n![APISetting](https://github.com/user-attachments/assets/601509da-8834-4156-8106-c145defa5710)\n\n![jwtsecret](https://github.com/user-attachments/assets/887a3b56-2f70-4dce-be12-e53b1bb52556)\n\nCreate a `todo` table.\n\n![createTable](https://github.com/user-attachments/assets/d3f8d608-2219-4882-8340-2542a28d1810)\n\nAdd a `title` (text type) column and click `Save`.\n\n![createTable2](https://github.com/user-attachments/assets/ffdaa8a1-4982-4589-a6a8-49024cea5946)\n\nInsert some sample data.\n\n![createTable3](https://github.com/user-attachments/assets/2fada978-8f2b-437b-b6c2-1948b2c3ee05)\n\nSet an RLS policy on the `todo` table to restrict access to users without the `Authenticated` role.\n\n```sql\nalter policy \"JWT Authenticated can view todo\"\non \"public\".\"todo\"\nto public\nusing (\n  ((auth.jwt() -\u003e 'userRoles'::text) ? 'Authenticated'::text)\n);\n```\n\n![jwt](https://github.com/user-attachments/assets/a8ada4bb-a8e5-42f9-b056-8c16e341c645)\n\nClick `Save Policy`.\n\n## Running the Application\n\nCreate a `.env.local` file:\n\n```bash\n# .env.local\nAUTH0_SECRET=any-secure-value\nAUTH0_BASE_URL=http://localhost:3000\nAUTH0_ISSUER_BASE_URL=https://\u003cyour-tenant\u003e.auth0.com\nAUTH0_CLIENT_ID=your-client-id\nAUTH0_CLIENT_SECRET=your-client-secret\nNEXT_PUBLIC_SUPABASE_URL=your-supabase-url\nNEXT_PUBLIC_SUPABASE_ANON_KEY=your-supabase-anon-key\nSUPABASE_JWT_SECRET=your-supabase-jwt-secret\n```\n\nStart the application and visit http://localhost:3000.\n\n```bash\npnpm dev\n```\n\n![Login](https://github.com/user-attachments/assets/60e18305-431b-4a82-943e-6f799b306b87)\n\nClick `Login` and authenticate via email or Google OAuth. Then, visit http://localhost:3000/protected to verify data retrieval.\n\n![afterLogin](https://github.com/user-attachments/assets/0560986f-e037-42b9-8c84-3aaec014843a)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmidoru0121%2Fnextjs-auth0-supabase-integration-example","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmidoru0121%2Fnextjs-auth0-supabase-integration-example","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmidoru0121%2Fnextjs-auth0-supabase-integration-example/lists"}