mirror of
https://github.com/directus/directus.git
synced 2026-04-25 03:00:53 -04:00
Return 401 status code for expired tokens (#12281)
* Refresh token when it's expired & retry request * move refresh token interceptor in autoRefresh flag * add TOKEN_EXPIRED exception * update interceptor condition & fix autoRefreshJob * update docs * revert auth drivers changes * remove unused imports * undo sdk auth refresh changes
This commit is contained in:
@@ -13,6 +13,7 @@ export * from './method-not-allowed';
|
||||
export * from './range-not-satisfiable';
|
||||
export * from './route-not-found';
|
||||
export * from './service-unavailable';
|
||||
export * from './token-expired';
|
||||
export * from './unprocessable-entity';
|
||||
export * from './unsupported-media-type';
|
||||
export * from './user-suspended';
|
||||
|
||||
7
api/src/exceptions/token-expired.ts
Normal file
7
api/src/exceptions/token-expired.ts
Normal file
@@ -0,0 +1,7 @@
|
||||
import { BaseException } from '@directus/shared/exceptions';
|
||||
|
||||
export class TokenExpiredException extends BaseException {
|
||||
constructor(message = 'Token expired.') {
|
||||
super(message, 401, 'TOKEN_EXPIRED');
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
import jwt, { JsonWebTokenError, TokenExpiredError } from 'jsonwebtoken';
|
||||
import { DirectusTokenPayload } from '../types';
|
||||
import { InvalidTokenException, ServiceUnavailableException } from '../exceptions';
|
||||
import { InvalidTokenException, ServiceUnavailableException, TokenExpiredException } from '../exceptions';
|
||||
|
||||
export function verifyAccessJWT(token: string, secret: string): DirectusTokenPayload {
|
||||
let payload;
|
||||
@@ -11,7 +11,7 @@ export function verifyAccessJWT(token: string, secret: string): DirectusTokenPay
|
||||
}) as Record<string, any>;
|
||||
} catch (err) {
|
||||
if (err instanceof TokenExpiredError) {
|
||||
throw new InvalidTokenException('Token expired.');
|
||||
throw new TokenExpiredException();
|
||||
} else if (err instanceof JsonWebTokenError) {
|
||||
throw new InvalidTokenException('Token invalid.');
|
||||
} else {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { verifyAccessJWT } from '../../src/utils/jwt';
|
||||
import jwt from 'jsonwebtoken';
|
||||
import { InvalidTokenException, ServiceUnavailableException } from '../../src/exceptions';
|
||||
import { InvalidTokenException, ServiceUnavailableException, TokenExpiredException } from '../../src/exceptions';
|
||||
import { DirectusTokenPayload } from '../../src/types';
|
||||
|
||||
const payload: DirectusTokenPayload = { role: null, app_access: false, admin_access: false };
|
||||
@@ -13,10 +13,14 @@ test('Returns the payload of a correctly signed token', () => {
|
||||
expect(result).toEqual(payload);
|
||||
});
|
||||
|
||||
test('Throws TokenExpiredException when token used has expired', () => {
|
||||
const token = jwt.sign({ ...payload, exp: new Date().getTime() / 1000 - 500 }, secret, options);
|
||||
expect(() => verifyAccessJWT(token, secret)).toThrow(TokenExpiredException);
|
||||
});
|
||||
|
||||
const InvalidTokenCases = {
|
||||
'wrong issuer': jwt.sign(payload, secret, { issuer: 'wrong' }),
|
||||
'wrong secret': jwt.sign(payload, 'wrong-secret', options),
|
||||
expired: jwt.sign({ ...payload, exp: new Date().getTime() / 1000 - 500 }, secret, options),
|
||||
'string payload': jwt.sign('illegal payload', secret),
|
||||
'missing properties in token payload': jwt.sign({ role: null }, secret, options),
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user