mirror of
https://github.com/jonasroussel/dart_jsonwebtoken.git
synced 2025-06-30 16:46:37 +08:00
v2.8.0
This commit is contained in:
@ -1,3 +1,8 @@
|
|||||||
|
## 2.8.0
|
||||||
|
|
||||||
|
- **BREAKING CHANGE**: Renaming all JWT...Error to JWT...Exception (https://github.com/jonasroussel/dart_jsonwebtoken/pull/42)
|
||||||
|
- Fixing assert message (https://github.com/jonasroussel/dart_jsonwebtoken/pull/42)
|
||||||
|
|
||||||
## 2.7.1
|
## 2.7.1
|
||||||
|
|
||||||
- Migrating from `pedantic` to `lints`
|
- Migrating from `pedantic` to `lints`
|
||||||
|
@ -52,15 +52,10 @@ try {
|
|||||||
final jwt = JWT.verify(token, SecretKey('secret passphrase'));
|
final jwt = JWT.verify(token, SecretKey('secret passphrase'));
|
||||||
|
|
||||||
print('Payload: ${jwt.payload}');
|
print('Payload: ${jwt.payload}');
|
||||||
|
} on JWTExpiredException {
|
||||||
} on JWTExpiredError {
|
|
||||||
|
|
||||||
print('jwt expired');
|
print('jwt expired');
|
||||||
|
} on JWTException catch (ex) {
|
||||||
} on JWTError catch (ex) {
|
|
||||||
|
|
||||||
print(ex.message); // ex: invalid signature
|
print(ex.message); // ex: invalid signature
|
||||||
|
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -45,9 +45,9 @@ void hs256() {
|
|||||||
final jwt = JWT.verify(token, SecretKey('secret passphrase'));
|
final jwt = JWT.verify(token, SecretKey('secret passphrase'));
|
||||||
|
|
||||||
print('Payload: ${jwt.payload}');
|
print('Payload: ${jwt.payload}');
|
||||||
} on JWTExpiredError {
|
} on JWTExpiredException {
|
||||||
print('jwt expired');
|
print('jwt expired');
|
||||||
} on JWTError catch (ex) {
|
} on JWTException catch (ex) {
|
||||||
print(ex.message); // ex: invalid signature
|
print(ex.message); // ex: invalid signature
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -88,9 +88,9 @@ void rs256() {
|
|||||||
final jwt = JWT.verify(token, key);
|
final jwt = JWT.verify(token, key);
|
||||||
|
|
||||||
print('Payload: ${jwt.payload}');
|
print('Payload: ${jwt.payload}');
|
||||||
} on JWTExpiredError {
|
} on JWTExpiredException {
|
||||||
print('jwt expired');
|
print('jwt expired');
|
||||||
} on JWTError catch (ex) {
|
} on JWTException catch (ex) {
|
||||||
print(ex.message); // ex: invalid signature
|
print(ex.message); // ex: invalid signature
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -131,9 +131,9 @@ void es256() {
|
|||||||
final jwt = JWT.verify(token, key);
|
final jwt = JWT.verify(token, key);
|
||||||
|
|
||||||
print('Payload: ${jwt.payload}');
|
print('Payload: ${jwt.payload}');
|
||||||
} on JWTExpiredError {
|
} on JWTExpiredException {
|
||||||
print('jwt expired');
|
print('jwt expired');
|
||||||
} on JWTError catch (ex) {
|
} on JWTException catch (ex) {
|
||||||
print(ex.message); // ex: invalid signature
|
print(ex.message); // ex: invalid signature
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
library jsonwebtoken;
|
library jsonwebtoken;
|
||||||
|
|
||||||
export 'src/jwt.dart';
|
export 'src/jwt.dart';
|
||||||
export 'src/errors.dart';
|
export 'src/exceptions.dart';
|
||||||
export 'src/algorithms.dart';
|
export 'src/algorithms.dart';
|
||||||
export 'src/keys.dart';
|
export 'src/keys.dart';
|
||||||
|
@ -5,7 +5,7 @@ import 'package:crypto/crypto.dart';
|
|||||||
import 'package:pointycastle/pointycastle.dart' as pc;
|
import 'package:pointycastle/pointycastle.dart' as pc;
|
||||||
|
|
||||||
import 'package:ed25519_edwards/ed25519_edwards.dart' as ed;
|
import 'package:ed25519_edwards/ed25519_edwards.dart' as ed;
|
||||||
import 'errors.dart';
|
import 'exceptions.dart';
|
||||||
import 'keys.dart';
|
import 'keys.dart';
|
||||||
import 'utils.dart';
|
import 'utils.dart';
|
||||||
|
|
||||||
@ -64,7 +64,7 @@ abstract class JWTAlgorithm {
|
|||||||
case 'EdDSA':
|
case 'EdDSA':
|
||||||
return JWTAlgorithm.EdDSA;
|
return JWTAlgorithm.EdDSA;
|
||||||
default:
|
default:
|
||||||
throw JWTInvalidError('unknown algorithm');
|
throw JWTInvalidException('unknown algorithm');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,55 +0,0 @@
|
|||||||
/// JWTError objects thrown in the case of a jwt sign or verify failure.
|
|
||||||
class JWTError extends Error {
|
|
||||||
JWTError(this.message);
|
|
||||||
|
|
||||||
/// Describes the error thrown
|
|
||||||
final String message;
|
|
||||||
|
|
||||||
@override
|
|
||||||
String toString() => 'JWTError: $message';
|
|
||||||
}
|
|
||||||
|
|
||||||
/// An error thrown when jwt is invalid
|
|
||||||
class JWTInvalidError extends JWTError {
|
|
||||||
JWTInvalidError(String message) : super(message);
|
|
||||||
|
|
||||||
@override
|
|
||||||
String toString() => 'JWTInvalidError: $message';
|
|
||||||
}
|
|
||||||
|
|
||||||
/// An error thrown when jwt is expired
|
|
||||||
class JWTExpiredError extends JWTError {
|
|
||||||
JWTExpiredError() : super('jwt expired');
|
|
||||||
|
|
||||||
@override
|
|
||||||
String toString() => 'JWTExpiredError: $message';
|
|
||||||
}
|
|
||||||
|
|
||||||
/// An error thrown when jwt is not active
|
|
||||||
class JWTNotActiveError extends JWTError {
|
|
||||||
JWTNotActiveError() : super('jwt not active');
|
|
||||||
|
|
||||||
@override
|
|
||||||
String toString() => 'JWTNotActiveError: $message';
|
|
||||||
}
|
|
||||||
|
|
||||||
/// An error thrown when parsing failed
|
|
||||||
class JWTParseError extends JWTError {
|
|
||||||
JWTParseError(String message) : super(message);
|
|
||||||
|
|
||||||
@override
|
|
||||||
String toString() => 'JWTParseError: $message';
|
|
||||||
}
|
|
||||||
|
|
||||||
/// An error thrown by default
|
|
||||||
class JWTUndefinedError extends JWTError {
|
|
||||||
JWTUndefinedError(this.error) : super(error.toString());
|
|
||||||
|
|
||||||
final Error error;
|
|
||||||
|
|
||||||
@override
|
|
||||||
String toString() => 'JWTUndefinedError: $message';
|
|
||||||
|
|
||||||
@override
|
|
||||||
StackTrace? get stackTrace => error.stackTrace;
|
|
||||||
}
|
|
51
lib/src/exceptions.dart
Normal file
51
lib/src/exceptions.dart
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
/// JWTException objects thrown in the case of a jwt sign or verify failure.
|
||||||
|
class JWTException implements Exception {
|
||||||
|
JWTException(this.message);
|
||||||
|
|
||||||
|
final String message;
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() => 'JWTException: $message';
|
||||||
|
}
|
||||||
|
|
||||||
|
/// An exception thrown when jwt is invalid
|
||||||
|
class JWTInvalidException extends JWTException {
|
||||||
|
JWTInvalidException(String message) : super(message);
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() => 'JWTInvalidException: $message';
|
||||||
|
}
|
||||||
|
|
||||||
|
/// An exception thrown when jwt is expired
|
||||||
|
class JWTExpiredException extends JWTException {
|
||||||
|
JWTExpiredException() : super('jwt expired');
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() => 'JWTExpiredException: $message';
|
||||||
|
}
|
||||||
|
|
||||||
|
/// An exception thrown when jwt is not active
|
||||||
|
class JWTNotActiveException extends JWTException {
|
||||||
|
JWTNotActiveException() : super('jwt not active');
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() => 'JWTNotActiveException: $message';
|
||||||
|
}
|
||||||
|
|
||||||
|
/// An exception thrown when parsing failed
|
||||||
|
class JWTParseException extends JWTException {
|
||||||
|
JWTParseException(String message) : super(message);
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() => 'JWTParseException: $message';
|
||||||
|
}
|
||||||
|
|
||||||
|
/// An exception thrown by default
|
||||||
|
class JWTUndefinedException extends JWTException {
|
||||||
|
JWTUndefinedException(Exception ex, this.stackTrace) : super(ex.toString());
|
||||||
|
|
||||||
|
final StackTrace stackTrace;
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() => 'JWTUndefinedException: $message';
|
||||||
|
}
|
@ -5,7 +5,7 @@ import 'dart:typed_data';
|
|||||||
import 'package:collection/collection.dart';
|
import 'package:collection/collection.dart';
|
||||||
|
|
||||||
import 'algorithms.dart';
|
import 'algorithms.dart';
|
||||||
import 'errors.dart';
|
import 'exceptions.dart';
|
||||||
import 'keys.dart';
|
import 'keys.dart';
|
||||||
import 'utils.dart';
|
import 'utils.dart';
|
||||||
|
|
||||||
@ -34,11 +34,11 @@ class JWT {
|
|||||||
final header = jsonBase64.decode(base64Padded(parts[0]));
|
final header = jsonBase64.decode(base64Padded(parts[0]));
|
||||||
|
|
||||||
if (header == null || header is! Map<String, dynamic>) {
|
if (header == null || header is! Map<String, dynamic>) {
|
||||||
throw JWTInvalidError('invalid header');
|
throw JWTInvalidException('invalid header');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (checkHeaderType && header['typ'] != 'JWT') {
|
if (checkHeaderType && header['typ'] != 'JWT') {
|
||||||
throw JWTInvalidError('not a jwt');
|
throw JWTInvalidException('not a jwt');
|
||||||
}
|
}
|
||||||
|
|
||||||
final algorithm = JWTAlgorithm.fromName(header['alg']);
|
final algorithm = JWTAlgorithm.fromName(header['alg']);
|
||||||
@ -47,7 +47,7 @@ class JWT {
|
|||||||
final signature = base64Url.decode(base64Padded(parts[2]));
|
final signature = base64Url.decode(base64Padded(parts[2]));
|
||||||
|
|
||||||
if (!algorithm.verify(key, Uint8List.fromList(body), signature)) {
|
if (!algorithm.verify(key, Uint8List.fromList(body), signature)) {
|
||||||
throw JWTInvalidError('invalid signature');
|
throw JWTInvalidException('invalid signature');
|
||||||
}
|
}
|
||||||
|
|
||||||
dynamic payload;
|
dynamic payload;
|
||||||
@ -65,7 +65,7 @@ class JWT {
|
|||||||
payload['exp'] * 1000,
|
payload['exp'] * 1000,
|
||||||
);
|
);
|
||||||
if (exp.isBefore(DateTime.now())) {
|
if (exp.isBefore(DateTime.now())) {
|
||||||
throw JWTExpiredError();
|
throw JWTExpiredException();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -75,20 +75,20 @@ class JWT {
|
|||||||
payload['nbf'] * 1000,
|
payload['nbf'] * 1000,
|
||||||
);
|
);
|
||||||
if (nbf.isAfter(DateTime.now())) {
|
if (nbf.isAfter(DateTime.now())) {
|
||||||
throw JWTNotActiveError();
|
throw JWTNotActiveException();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// iat
|
// iat
|
||||||
if (issueAt != null) {
|
if (issueAt != null) {
|
||||||
if (!payload.containsKey('iat')) {
|
if (!payload.containsKey('iat')) {
|
||||||
throw JWTInvalidError('invalid issue at');
|
throw JWTInvalidException('invalid issue at');
|
||||||
}
|
}
|
||||||
final iat = DateTime.fromMillisecondsSinceEpoch(
|
final iat = DateTime.fromMillisecondsSinceEpoch(
|
||||||
payload['iat'] * 1000,
|
payload['iat'] * 1000,
|
||||||
);
|
);
|
||||||
if (!iat.isAtSameMomentAs(DateTime.now())) {
|
if (!iat.isAtSameMomentAs(DateTime.now())) {
|
||||||
throw JWTInvalidError('invalid issue at');
|
throw JWTInvalidException('invalid issue at');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -96,34 +96,34 @@ class JWT {
|
|||||||
if (audience != null) {
|
if (audience != null) {
|
||||||
if (payload.containsKey('aud')) {
|
if (payload.containsKey('aud')) {
|
||||||
if (payload['aud'] is String && payload['aud'] != audience.first) {
|
if (payload['aud'] is String && payload['aud'] != audience.first) {
|
||||||
throw JWTInvalidError('invalid audience');
|
throw JWTInvalidException('invalid audience');
|
||||||
} else if (payload['aud'] is List &&
|
} else if (payload['aud'] is List &&
|
||||||
!ListEquality().equals(payload['aud'], audience)) {
|
!ListEquality().equals(payload['aud'], audience)) {
|
||||||
throw JWTInvalidError('invalid audience');
|
throw JWTInvalidException('invalid audience');
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
throw JWTInvalidError('invalid audience');
|
throw JWTInvalidException('invalid audience');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// sub
|
// sub
|
||||||
if (subject != null) {
|
if (subject != null) {
|
||||||
if (!payload.containsKey('sub') || payload['sub'] != subject) {
|
if (!payload.containsKey('sub') || payload['sub'] != subject) {
|
||||||
throw JWTInvalidError('invalid subject');
|
throw JWTInvalidException('invalid subject');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// iss
|
// iss
|
||||||
if (issuer != null) {
|
if (issuer != null) {
|
||||||
if (!payload.containsKey('iss') || payload['iss'] != issuer) {
|
if (!payload.containsKey('iss') || payload['iss'] != issuer) {
|
||||||
throw JWTInvalidError('invalid issuer');
|
throw JWTInvalidException('invalid issuer');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// jti
|
// jti
|
||||||
if (jwtId != null) {
|
if (jwtId != null) {
|
||||||
if (!payload.containsKey('jti') || payload['jti'] != jwtId) {
|
if (!payload.containsKey('jti') || payload['jti'] != jwtId) {
|
||||||
throw JWTInvalidError('invalid jwt id');
|
throw JWTInvalidException('invalid jwt id');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -138,16 +138,16 @@ class JWT {
|
|||||||
} else {
|
} else {
|
||||||
return JWT(payload);
|
return JWT(payload);
|
||||||
}
|
}
|
||||||
} catch (ex) {
|
} catch (ex, stackTrace) {
|
||||||
if (ex is Error && ex is! JWTError) {
|
if (ex is Exception && ex is! JWTException) {
|
||||||
throw JWTUndefinedError(ex);
|
throw JWTUndefinedException(ex, stackTrace);
|
||||||
} else {
|
} else {
|
||||||
rethrow;
|
rethrow;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Exactly like `verify`, just return null instead of throwing errors.
|
/// Exactly like `verify`, just return null instead of throwing exceptions.
|
||||||
static JWT? tryVerify(
|
static JWT? tryVerify(
|
||||||
String token,
|
String token,
|
||||||
JWTKey key, {
|
JWTKey key, {
|
||||||
@ -200,16 +200,16 @@ class JWT {
|
|||||||
header: header,
|
header: header,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
} catch (ex) {
|
} catch (ex, stackTrace) {
|
||||||
if (ex is Error && ex is! JWTError) {
|
if (ex is Exception && ex is! JWTException) {
|
||||||
throw JWTUndefinedError(ex);
|
throw JWTUndefinedException(ex, stackTrace);
|
||||||
} else {
|
} else {
|
||||||
rethrow;
|
rethrow;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Exactly like `decode`, just return `null` instead of throwing errors.
|
/// Exactly like `decode`, just return `null` instead of throwing exceptions.
|
||||||
static JWT? tryDecode(String token) {
|
static JWT? tryDecode(String token) {
|
||||||
try {
|
try {
|
||||||
return decode(token);
|
return decode(token);
|
||||||
@ -297,7 +297,7 @@ class JWT {
|
|||||||
: jsonBase64.encode(payload),
|
: jsonBase64.encode(payload),
|
||||||
);
|
);
|
||||||
} catch (ex) {
|
} catch (ex) {
|
||||||
throw JWTError(
|
throw JWTException(
|
||||||
'invalid payload json format (Map keys must be String type)',
|
'invalid payload json format (Map keys must be String type)',
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -313,16 +313,16 @@ class JWT {
|
|||||||
);
|
);
|
||||||
|
|
||||||
return body + '.' + signature;
|
return body + '.' + signature;
|
||||||
} catch (ex) {
|
} catch (ex, stackTrace) {
|
||||||
if (ex is Error && ex is! JWTError) {
|
if (ex is Exception && ex is! JWTException) {
|
||||||
throw JWTUndefinedError(ex);
|
throw JWTUndefinedException(ex, stackTrace);
|
||||||
} else {
|
} else {
|
||||||
rethrow;
|
rethrow;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Exactly like `sign`, just return `null` instead of throwing errors.
|
/// Exactly like `sign`, just return `null` instead of throwing exceptions.
|
||||||
String? trySign(
|
String? trySign(
|
||||||
JWTKey key, {
|
JWTKey key, {
|
||||||
JWTAlgorithm algorithm = JWTAlgorithm.HS256,
|
JWTAlgorithm algorithm = JWTAlgorithm.HS256,
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import 'package:pointycastle/pointycastle.dart' as pc;
|
import 'package:pointycastle/pointycastle.dart' as pc;
|
||||||
|
|
||||||
import 'package:ed25519_edwards/ed25519_edwards.dart' as ed;
|
import 'package:ed25519_edwards/ed25519_edwards.dart' as ed;
|
||||||
import 'errors.dart';
|
import 'exceptions.dart';
|
||||||
import 'crypto_utils.dart';
|
import 'crypto_utils.dart';
|
||||||
|
|
||||||
abstract class JWTKey {}
|
abstract class JWTKey {}
|
||||||
@ -55,7 +55,7 @@ class ECPrivateKey extends JWTKey {
|
|||||||
final _params = _key.parameters;
|
final _params = _key.parameters;
|
||||||
|
|
||||||
if (_params == null) {
|
if (_params == null) {
|
||||||
throw JWTParseError('ECPrivateKey parameters are invalid');
|
throw JWTParseException('ECPrivateKey parameters are invalid');
|
||||||
}
|
}
|
||||||
|
|
||||||
key = _key;
|
key = _key;
|
||||||
@ -66,7 +66,7 @@ class ECPrivateKey extends JWTKey {
|
|||||||
final _params = _key.parameters;
|
final _params = _key.parameters;
|
||||||
|
|
||||||
if (_params == null) {
|
if (_params == null) {
|
||||||
throw JWTParseError('ECPrivateKey parameters are invalid');
|
throw JWTParseException('ECPrivateKey parameters are invalid');
|
||||||
}
|
}
|
||||||
|
|
||||||
key = _key;
|
key = _key;
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
name: dart_jsonwebtoken
|
name: dart_jsonwebtoken
|
||||||
description: A dart implementation of the famous javascript library 'jsonwebtoken' (JWT).
|
description: A dart implementation of the famous javascript library 'jsonwebtoken' (JWT).
|
||||||
version: 2.7.1
|
version: 2.8.0
|
||||||
repository: https://github.com/jonasroussel/dart_jsonwebtoken
|
repository: https://github.com/jonasroussel/dart_jsonwebtoken
|
||||||
homepage: https://github.com/jonasroussel/dart_jsonwebtoken#readme
|
homepage: https://github.com/jonasroussel/dart_jsonwebtoken#readme
|
||||||
|
|
||||||
environment:
|
environment:
|
||||||
sdk: ">=2.12.0 <3.0.0"
|
sdk: ">=2.12.0 <4.0.0"
|
||||||
|
|
||||||
false_secrets:
|
false_secrets:
|
||||||
- /example/ec_private.pem
|
- /example/ec_private.pem
|
||||||
|
Reference in New Issue
Block a user