Skip to content
Closed
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 36 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,42 @@ In the above example the `/admin` page will require a user to be signed in, wher

`unauthenticatedPaths` uses the same glob logic as the [Next.js matcher](https://nextjs.org/docs/pages/building-your-application/routing/middleware#matcher).

### Middleware auth and server actions

Using [server actions](https://nextjs.org/docs/app/building-your-application/data-fetching/server-actions-and-mutations) with middleware auth mode can result in unexpected CORS errors if you don't wrap your server action call in a try/catch block. This is because a call to a server action without an existing session will be intercepted by the middleware and a redirect to AuthKit will be attempted, which will trigger a CORS error.

Wrapping your server action call in a try/catch block will allow you to either display an error or redirect the user:

```jsx
'use client';

import { serverFunction } from '../../server-function';
import { useRouter } from 'next/navigation';

export default function TestPage() {
const router = useRouter();

const handleClick = async () => {
try {
const data = await serverFunction();

// Do something with data
} catch (e) {
// In the case of a CORS error, redirect user to login page
router.push('/login');
}
};

return (
<>
<button type="button" onClick={handleClick}>
Trigger server function
</button>
</>
);
}
```

### Signing out

Use the `signOut` method to sign out the current logged in user and redirect to your app's homepage. The homepage redirect is set in your WorkOS dashboard settings under "Redirect".
Expand Down
168 changes: 148 additions & 20 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@
"eslint": "^8.29.0",
"eslint-config-prettier": "^9.1.0",
"eslint-plugin-require-extensions": "^0.1.3",
"next": "^14.1.3",
"next": "^14.2.5",
"typescript": "5.4.2",
"typescript-eslint": "^7.2.0"
},
Expand Down
13 changes: 13 additions & 0 deletions src/session.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,19 @@ async function updateSession(request: NextRequest, debug: boolean, middlewareAut
// If the user is logged out and this path isn't on the allowlist for logged out paths, redirect to AuthKit.
if (middlewareAuth.enabled && matchedPaths.length === 0 && !session) {
if (debug) console.log('Unauthenticated user on protected route, redirecting to AuthKit');

const serverAction = request.headers.get('next-action');

// If the request is a server action, then we're likely to run afoul of CORS protections
// as the request might have come from the client as a server function.
// In that case we warn the user and continue, which will likely result in a CORS error.
if (serverAction !== null) {
if (debug)
console.warn(
`🚫 Server action detected without a valid session in middleware auth mode. Make sure you catch the CORS error and either redirect or handle the error gracefully. See the authkit-nextjs readme for more information: https://github.com/workos/authkit-nextjs`,
);
}

return NextResponse.redirect(await getAuthorizationUrl({ returnPathname: new URL(request.url).pathname }));
}

Expand Down