Skip to content

Commit 35c5bea

Browse files
authored
chore(express): Deprecate requireAuth() helper (#8241)
1 parent 1564a8c commit 35c5bea

3 files changed

Lines changed: 77 additions & 17 deletions

File tree

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
---
2+
'@clerk/express': minor
3+
---
4+
5+
Deprecated `requireAuth()` middleware. It will be removed in the next major version.
6+
7+
The `requireAuth()` middleware redirects unauthenticated requests to a sign-in page, which is often unexpected for API routes where a 401 response is more appropriate. Use `clerkMiddleware()` with `getAuth()` instead for explicit control over authentication behavior.
8+
9+
**Before (deprecated):**
10+
11+
```js
12+
import { requireAuth } from '@clerk/express';
13+
14+
app.get('/api/protected', requireAuth(), (req, res) => {
15+
// handle authenticated request
16+
});
17+
```
18+
19+
**After (recommended):**
20+
21+
```js
22+
import { clerkMiddleware, getAuth } from '@clerk/express';
23+
24+
app.use(clerkMiddleware());
25+
26+
app.get('/api/protected', (req, res) => {
27+
const { userId } = getAuth(req);
28+
if (!userId) {
29+
return res.status(401).json({ error: 'Unauthorized' });
30+
}
31+
// handle authenticated request
32+
});
33+
```

packages/express/src/__tests__/requireAuth.test.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,19 @@ vi.mock('../authenticateRequest', () => ({
1515
authenticateRequest: (options = {}) => mockAuthenticateRequest(options),
1616
}));
1717

18+
const { mockDeprecated } = vi.hoisted(() => ({
19+
mockDeprecated: vi.fn(),
20+
}));
21+
vi.mock('@clerk/shared/deprecated', () => ({
22+
deprecated: mockDeprecated,
23+
}));
24+
1825
describe('requireAuth', () => {
1926
beforeEach(() => {
2027
vi.clearAllMocks();
2128
mockAuthenticateAndDecorateRequest = vi.fn();
2229
mockAuthenticateRequest = vi.fn();
30+
mockDeprecated.mockClear();
2331
});
2432

2533
it('should redirect to sign-in page when user is not authenticated', async () => {
@@ -97,4 +105,20 @@ describe('requireAuth', () => {
97105
expect(response.status).toBe(302);
98106
expect(response.headers.location).toBe('/sign-in');
99107
});
108+
109+
it('should emit a deprecation warning when called', async () => {
110+
mockAuthenticateAndDecorateRequest.mockImplementation((): RequestHandler => {
111+
return (req, _res, next) => {
112+
Object.assign(req, mockRequestWithAuth({ userId: 'user_123' }));
113+
next();
114+
};
115+
});
116+
117+
await runMiddleware(requireAuth());
118+
119+
expect(mockDeprecated).toHaveBeenCalledWith(
120+
'requireAuth',
121+
'Use `clerkMiddleware()` with `getAuth()` instead. `requireAuth` will be removed in the next major version.',
122+
);
123+
});
100124
});

packages/express/src/requireAuth.ts

Lines changed: 20 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { deprecated } from '@clerk/shared/deprecated';
12
import type { RequestHandler } from 'express';
23

34
import { authenticateAndDecorateRequest } from './authenticateRequest';
@@ -7,30 +8,27 @@ import type { ClerkMiddlewareOptions, ExpressRequestWithAuth } from './types';
78
* Middleware to require authentication for user requests.
89
* Redirects unauthenticated requests to the sign-in url.
910
*
11+
* @deprecated Use `clerkMiddleware()` with `getAuth()` instead.
12+
* `requireAuth` will be removed in the next major version.
13+
*
1014
* @example
11-
* // Basic usage
15+
* // Before (deprecated)
1216
* import { requireAuth } from '@clerk/express'
13-
*
14-
* router.use(requireAuth())
15-
* //or
1617
* router.get('/path', requireAuth(), getHandler)
1718
*
1819
* @example
19-
* // Customizing the sign-in path
20-
* router.use(requireAuth({ signInUrl: '/sign-in' }))
20+
* // After (recommended)
21+
* import { clerkMiddleware, getAuth } from '@clerk/express'
2122
*
22-
* @example
23-
* // Combining with permission check
24-
* import { getAuth, requireAuth } from '@clerk/express'
23+
* app.use(clerkMiddleware())
2524
*
26-
* const hasPermission = (req, res, next) => {
27-
* const auth = getAuth(req)
28-
* if (!auth.has({ permission: 'permission' })) {
29-
* return res.status(403).send('Forbidden')
30-
* }
31-
* return next()
32-
* }
33-
* router.get('/path', requireAuth(), hasPermission, getHandler)
25+
* app.get('/api/protected', (req, res) => {
26+
* const { userId } = getAuth(req);
27+
* if (!userId) {
28+
* return res.status(401).json({ error: 'Unauthorized' });
29+
* }
30+
* // handle authenticated request
31+
* })
3432
*/
3533
export const requireAuth = (options: ClerkMiddlewareOptions = {}): RequestHandler => {
3634
const authMiddleware = authenticateAndDecorateRequest({
@@ -39,6 +37,11 @@ export const requireAuth = (options: ClerkMiddlewareOptions = {}): RequestHandle
3937
});
4038

4139
return (request, response, next) => {
40+
deprecated(
41+
'requireAuth',
42+
'Use `clerkMiddleware()` with `getAuth()` instead. `requireAuth` will be removed in the next major version.',
43+
);
44+
4245
authMiddleware(request, response, err => {
4346
if (err) {
4447
return next(err);

0 commit comments

Comments
 (0)