-
Notifications
You must be signed in to change notification settings - Fork 3.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix(api): ApiKey auth guard performance #4972
Conversation
|
||
const AUTH_STRATEGIES: Provider[] = []; | ||
const AUTH_STRATEGIES: Provider[] = [JwtStrategy, ApiKeyStrategy, JwtSubscriberStrategy]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Moving the passport strategies out to where they belong.
const user = jwt.decode(token) as IJwtPayload; | ||
if (!user) return false; | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is handled in the Authentication flow, and shouldn't be part of Authorization.
|
||
const user = jwt.decode(token) as IJwtPayload; | ||
if (!user) return false; | ||
if (!user.environmentId) return false; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As above, this is handled in the Authentication flow, and shouldn't be part of Authorization.
environmentId: payload.environmentId, | ||
organizationId: payload.organizationId, | ||
}); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is now handled in a single place in the Auth Guard, for all Auth strategies.
|
||
return jwt.decode(token); | ||
return req.user; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
req.user
is always present now.
const { environment, user, key, error } = await this.getUserData({ | ||
apiKey, | ||
}); | ||
public async validateApiKey(apiKey: string): Promise<IJwtPayload> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Making sure the ApiKey validation returns the same interface as Bearer authentication.
} | ||
); | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not used.
}) | ||
private async getEnvironment({ apiKey }: { apiKey: string }) { | ||
return await this.environmentRepository.findByApiKey(apiKey); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not used.
|
||
async verifyJwt(jwt: string) { | ||
return this.jwtService.verify(jwt); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not used.
|
||
if (error) throw new UnauthorizedException(error); | ||
if (!environment) throw new UnauthorizedException('API Key not found'); | ||
if (!user) throw new UnauthorizedException('User not found'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The if(error)
check above already handles these exceptions.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
looks good to me 💎 just the comment from Dima
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Love how much the code became cleaner and optimized 🤩
The main concern i had was regarding auth.guard.ts file and the defaultStrategy
packages/application-generic/src/usecases/trigger-event/trigger-event.usecase.ts
Outdated
Show resolved
Hide resolved
}); | ||
} | ||
/** | ||
* This helps with sentry and other tools that need to know who the user is based on `id` property. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🚀
These changes broke a bunch of It may be a result of the Idempotency changes, but could be something else. Further investigation needed. |
I have ruled out Idempotency issues. It appears that the throttler guard is processing a different |
Turns out this was a simple fix. I'd changed the signature of the |
…-new-relic-alerts
…-new-relic-alerts
Added tests for both Bearer and ApiKey auth to make sure the auth logic and strategies are working as expected - 6ba5265 |
What change does this PR introduce?
Roles
guardRootEnvironment
guardUserSession
decoratorWhy was this change needed?
API requests using ApiKey authentication currently sign and decode a JWT token every request. The signing introduces considerable latency whilst the decoding adds unnecessary memory consumption.
We also needed an interface to retrieve User context from the request, regardless of auth scheme.
Other information (Screenshots)
Auth Guard Tests
![image](https://private-user-images.githubusercontent.com/32132657/290278569-3061f959-3089-4854-81ee-d3415f07be88.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3MjA2OTk4NzcsIm5iZiI6MTcyMDY5OTU3NywicGF0aCI6Ii8zMjEzMjY1Ny8yOTAyNzg1NjktMzA2MWY5NTktMzA4OS00ODU0LTgxZWUtZDM0MTVmMDdiZTg4LnBuZz9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFWQ09EWUxTQTUzUFFLNFpBJTJGMjAyNDA3MTElMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjQwNzExVDEyMDYxN1omWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPWY2YmFlMjM3OTE0MDNjYTg0ZjA5Nzg3MTNjM2YxYjUyNDliODE5MmMzZTQ2OTU2YjI4NmRhNDU1N2YzYTdlMTUmWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0JmFjdG9yX2lkPTAma2V5X2lkPTAmcmVwb19pZD0wIn0.pj9n6hoJkku5YFcL0XpJhhgIDfXlRXAqXRodb3ny76I)
ApiKey Auth Log
![image](https://private-user-images.githubusercontent.com/32132657/289987751-c05d3cd7-dc94-4b7c-9717-b7fe7d6b7a69.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3MjA2OTk4NzcsIm5iZiI6MTcyMDY5OTU3NywicGF0aCI6Ii8zMjEzMjY1Ny8yODk5ODc3NTEtYzA1ZDNjZDctZGM5NC00YjdjLTk3MTctYjdmZTdkNmI3YTY5LnBuZz9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFWQ09EWUxTQTUzUFFLNFpBJTJGMjAyNDA3MTElMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjQwNzExVDEyMDYxN1omWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPTVjNWJiZTJkNDYzMmRmNDE5YTg3MDY1N2ZkNzU4N2E4YjE3MmI3N2QyNmVmNDE0MTE4Y2ZlYjYxMmZkZmMzZWImWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0JmFjdG9yX2lkPTAma2V5X2lkPTAmcmVwb19pZD0wIn0.q_xMMWaAaYxLYdZurdtOk64zcrxNVFpeQ7A_jevv2Eo)
Bearer Auth Log
![image](https://private-user-images.githubusercontent.com/32132657/289988005-338d67f1-633b-4bbf-8601-027bcffeecea.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3MjA2OTk4NzcsIm5iZiI6MTcyMDY5OTU3NywicGF0aCI6Ii8zMjEzMjY1Ny8yODk5ODgwMDUtMzM4ZDY3ZjEtNjMzYi00YmJmLTg2MDEtMDI3YmNmZmVlY2VhLnBuZz9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFWQ09EWUxTQTUzUFFLNFpBJTJGMjAyNDA3MTElMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjQwNzExVDEyMDYxN1omWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPWRmNzhiZmU3MmMyN2E3MmNiNjhlNjQ5ODk1MmViMWFiZWU4YWZiZTU5OWMwMjZlMzExODQwOWZlZTgxZDg2ZjAmWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0JmFjdG9yX2lkPTAma2V5X2lkPTAmcmVwb19pZD0wIn0.7Jfq1PNODoJAFYcoptE9NWYevk-iDSoMKklvxmiDpvU)
No Auth Log
![image](https://private-user-images.githubusercontent.com/32132657/289988224-7f6b1482-cb44-47b4-8ffe-710d1111fa64.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3MjA2OTk4NzcsIm5iZiI6MTcyMDY5OTU3NywicGF0aCI6Ii8zMjEzMjY1Ny8yODk5ODgyMjQtN2Y2YjE0ODItY2I0NC00N2I0LThmZmUtNzEwZDExMTFmYTY0LnBuZz9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFWQ09EWUxTQTUzUFFLNFpBJTJGMjAyNDA3MTElMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjQwNzExVDEyMDYxN1omWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPWE1YTBjZmJjOWUzMGMxMjZjZDFiNjc3NmRjZDExYjJkOWQzZjI5NmZlMzM2N2FiNmUwYzVhODJmOTRiOTk3YmMmWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0JmFjdG9yX2lkPTAma2V5X2lkPTAmcmVwb19pZD0wIn0.t6WG8RVuXr0LeHHBBsmzTmywZYpZ8rvhVdIoAkLM_rY)