-
-
Notifications
You must be signed in to change notification settings - Fork 274
fix(gotrue): fix getClaims JWT token decoding #1288
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
Open
khensunny
wants to merge
1
commit into
supabase:main
Choose a base branch
from
khensunny:fix-getclaims-token-decoding
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Some comments aren't visible on the classic Files Changed page.
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,6 @@ | ||
| services: | ||
| gotrue: | ||
| # Minimal override for asymmetric JWT signing + JWKS publishing. | ||
| # Used with: docker compose -f docker-compose.yml -f docker-compose.jwk.yml up | ||
| environment: | ||
| GOTRUE_JWT_KEYS: '[{"kty":"EC","kid":"23203d4b-184b-4915-bb30-e70047967f88","use":"sig","key_ops":["sign","verify"],"alg":"ES256","ext":true,"d":"sVoSxECYxh-gfZFCYU3U8vbjH2cHSwtc4_uDmhMRIUo","crv":"P-256","x":"uXsLvkycPMsWg8v-8CGqbwhqCG9YNrlQKFyZL96puXo","y":"xGyOad6_Dg0UpiTmpdOP1kn9W8LNM3afTpqAv2ZHM8M"}]' |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,14 @@ | ||
| # GoTrue test environment configuration | ||
| # Copy this file to .env and configure for your test setup | ||
|
|
||
| # Default GoTrue URL and anon key | ||
| GOTRUE_URL=http://localhost:9998 | ||
| GOTRUE_TOKEN=anonKey | ||
|
|
||
| # Symmetric JWT signing (HS256) - used by default docker-compose.yml | ||
| GOTRUE_JWT_SECRET=37c304f8-51aa-419a-a1af-06154e63707a | ||
|
|
||
| # Asymmetric JWT signing (ES256) - used when docker-compose.jwk.yml is active | ||
| # Uncomment this line when running tests with JWK setup: | ||
| # docker compose -f infra/gotrue/docker-compose.yml -f infra/gotrue/docker-compose.jwk.yml up | ||
| # GOTRUE_JWT_KEYS=[{"kty":"EC","kid":"23203d4b-184b-4915-bb30-e70047967f88","use":"sig","key_ops":["sign","verify"],"alg":"ES256","ext":true,"d":"sVoSxECYxh-gfZFCYU3U8vbjH2cHSwtc4_uDmhMRIUo","crv":"P-256","x":"uXsLvkycPMsWg8v-8CGqbwhqCG9YNrlQKFyZL96puXo","y":"xGyOad6_Dg0UpiTmpdOP1kn9W8LNM3afTpqAv2ZHM8M"}] |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -3,6 +3,7 @@ import 'dart:convert'; | |
| import 'package:dart_jsonwebtoken/dart_jsonwebtoken.dart'; | ||
| import 'package:dotenv/dotenv.dart'; | ||
| import 'package:gotrue/gotrue.dart'; | ||
| import 'package:jose_plus/jose.dart' as jose; | ||
|
|
||
| /// Email of a user with unverified factor | ||
| const email1 = '[email protected]'; | ||
|
|
@@ -39,15 +40,66 @@ String getNewPhone() { | |
| return '$timestamp'; | ||
| } | ||
|
|
||
| /// Generates a service role JWT token for authentication with GoTrue. | ||
| /// | ||
| /// Supports two modes: | ||
| /// 1. Symmetric signing (HS256): Uses GOTRUE_JWT_SECRET | ||
| /// 2. Asymmetric signing (ES256/RS256): Uses GOTRUE_JWT_KEYS | ||
| /// | ||
| /// The mode is automatically detected based on the presence of GOTRUE_JWT_KEYS. | ||
| String getServiceRoleToken(DotEnv env) { | ||
| final jwtKeys = env['GOTRUE_JWT_KEYS']; | ||
|
|
||
| // If GOTRUE_JWT_KEYS is set, use asymmetric signing (ES256/RS256) | ||
| if (jwtKeys != null && jwtKeys.isNotEmpty) { | ||
| return _getServiceRoleTokenAsymmetric(jwtKeys); | ||
| } | ||
|
|
||
| // Otherwise, use symmetric signing (HS256) | ||
| final secret = | ||
| env['GOTRUE_JWT_SECRET'] ?? '37c304f8-51aa-419a-a1af-06154e63707a'; | ||
| return _getServiceRoleTokenSymmetric(secret); | ||
| } | ||
|
|
||
| /// Creates a service role token using symmetric HS256 signing. | ||
| String _getServiceRoleTokenSymmetric(String secret) { | ||
| return JWT( | ||
| { | ||
| 'role': 'service_role', | ||
| }, | ||
| ).sign( | ||
| SecretKey( | ||
| env['GOTRUE_JWT_SECRET'] ?? '37c304f8-51aa-419a-a1af-06154e63707a'), | ||
| ); | ||
| ).sign(SecretKey(secret)); | ||
| } | ||
|
|
||
khensunny marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| /// Creates a service role token using asymmetric signing (ES256/RS256). | ||
| /// | ||
| /// [jwtKeysJson] should be a JSON array of JWKs (JSON Web Keys), typically from the GOTRUE_JWT_KEYS environment variable. | ||
| /// The first key in the array is used to sign the token. | ||
| String _getServiceRoleTokenAsymmetric(String jwtKeysJson) { | ||
| try { | ||
| final List<dynamic> keysArray = json.decode(jwtKeysJson) as List<dynamic>; | ||
| if (keysArray.isEmpty) { | ||
| throw Exception('Input json array has no JWT keys'); | ||
| } | ||
|
|
||
| // Use the first key from the array | ||
| final keyData = keysArray.first as Map<String, dynamic>; | ||
| final jwk = jose.JsonWebKey.fromJson(keyData); | ||
|
|
||
| // Create JWT claims | ||
| final claims = jose.JsonWebTokenClaims.fromJson({ | ||
| 'role': 'service_role', | ||
| }); | ||
|
|
||
| // Create and sign the token | ||
| final builder = jose.JsonWebSignatureBuilder() | ||
| ..jsonContent = claims.toJson() | ||
| ..addRecipient(jwk, algorithm: keyData['alg'] as String?); | ||
|
|
||
| final jws = builder.build(); | ||
| return jws.toCompactSerialization(); | ||
| } catch (e) { | ||
| throw Exception('Failed to create asymmetric service role token: $e'); | ||
| } | ||
| } | ||
|
|
||
| /// Construct session data for a given expiration date | ||
|
|
||
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.