javascript icon indicating copy to clipboard operation
javascript copied to clipboard

feat(nextjs,edge,backend-core): Add getAuth and runClerkMiddleware pr…

Open igneel64 opened this issue 1 year ago • 1 comments

Draft proposal

Type of change

  • [ ] 🐛 Bug fix
  • [x] 🌟 New feature
  • [ ] 🔨 Breaking change
  • [ ] 📖 Refactoring / dependency upgrade / documentation
  • [ ] other:

Packages affected

  • [ ] @clerk/clerk-js
  • [ ] @clerk/clerk-react
  • [x] @clerk/nextjs
  • [ ] @clerk/remix
  • [ ] @clerk/types
  • [ ] @clerk/clerk-expo
  • [x] @clerk/backend-core
  • [ ] @clerk/clerk-sdk-node
  • [x] @clerk/edge
  • [ ] build/tooling/chore

Description

  • [x] npm test runs as expected.
  • [x] npm run build runs as expected.

Integration strategy proposal for Next.js 12.2 compatible APIs

This PR adds 2 new methods for use in the new middleware structure of Next.js > 12.2.

  • runClerkMiddleware should be run on the middleware file
  • getAuth can be run on both gssp and Node.js API routes
  • API calls work forgssp, middleware and Node.js API routes from the same import.
// gssp
import { getAuth, clerkApi } from "@clerk/nextjs/server";

export default function Home() {
  return ();
}

export async function getServerSideProps(ctx) {
  const auth = getAuth(ctx.res);

  const sessions = await clerkApi.sessions.getSessionList();
  console.log("gssp sessions: ", sessions);
  return { props: {} };
}

// middleware
import { NextRequest } from "next/server";
import { runClerkMiddleware, clerkApi } from "@clerk/nextjs/server";

export async function middleware(request: NextRequest) {
  const { auth, response } = await runClerkMiddleware(request);
  const sessions = await clerkApi.sessions.getSessionList();
  console.log("sessions middleware", sessions);
  return response;
}

The proposal uses a header(Clerk-Auth-Middleware) which is passed from the middleware file down to gssp and API routes. There getAuth retrieves the values from the decoded key etc., adds the appropriate getToken version and removes it from the client. In the worst case scenario where the client does not use getAuth, the header retrieved on the client is the decoded JWT.

Issues/12.2 stuff

  • Intersitital rewrite does not receive the Authorization header properly. Using NextResponse.rewrite does calls a proxy request on the Next.js server but does not seem to add any additional headers on the request, it only adds them on the final response. See more here. The only place I found which can add data on the original request is the query string which persists for the final rewrite request. This is a blocker for interstitial.
  • As it seems from GH the req object is immutable from the middleware so the getAuth method cannot retrieve data from the req but from the res object.
  • The experimental-edge API routes seem to run before the middleware file which seems unintuitive to me. Using experimental-edge API together with middleware seems to be having these issues.

WIP

  • Typings.
  • Testing more cases.
  • Add options on getAuth which were present on the wrappers such as authorizedParties etc.
  • Check if we can throw at some point when we detect no removal of Clerk-Auth-Middleware

Based on: https://www.notion.so/clerkdev/Next-js-12-2-New-integration-strategy-move-auth-to-middleware-ts-0293c1f53a134dc08ed9b4cfee7b06fd

igneel64 avatar Aug 02 '22 12:08 igneel64

Can you build an example repo showing the ordering problem for middleware vs edge api routes? That's very surprising.

I posted a comment on the issue of retrieving middleware data elsewhere, surprising there's an issue there.

Can continue the interstitial solution discussion in Slack.

Thanks!

colinclerk avatar Aug 04 '22 18:08 colinclerk