Skip to content

Commit dd570f0

Browse files
Andrew-Lees11djones6
authored andcommitted
fix: Set date coding strategy to seconds since 1970 (#26)
1 parent 49e69ef commit dd570f0

File tree

6 files changed

+23
-9
lines changed

6 files changed

+23
-9
lines changed

Sources/SwiftJWT/Claims.swift

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,9 @@ public extension Claims {
7676
}
7777

7878
func encode() throws -> String {
79-
let data = try JSONEncoder().encode(self)
79+
let jsonEncoder = JSONEncoder()
80+
jsonEncoder.dateEncodingStrategy = .secondsSince1970
81+
let data = try jsonEncoder.encode(self)
8082
return data.base64urlEncodedString()
8183
}
8284
}

Sources/SwiftJWT/Header.swift

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,9 @@ public struct Header: Codable {
9494
}
9595

9696
func encode() throws -> String {
97-
let data = try JSONEncoder().encode(self)
97+
let jsonEncoder = JSONEncoder()
98+
jsonEncoder.dateEncodingStrategy = .secondsSince1970
99+
let data = try jsonEncoder.encode(self)
98100
return data.base64urlEncodedString()
99101
}
100102
}

Sources/SwiftJWT/JWT.swift

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,8 +73,10 @@ public struct JWT<T: Claims>: Codable {
7373
guard JWT.verify(jwtString, using: verifier) else {
7474
throw JWTError.failedVerification
7575
}
76-
let header = try JSONDecoder().decode(Header.self, from: headerData)
77-
let claims = try JSONDecoder().decode(T.self, from: claimsData)
76+
let jsonDecoder = JSONDecoder()
77+
jsonDecoder.dateDecodingStrategy = .secondsSince1970
78+
let header = try jsonDecoder.decode(Header.self, from: headerData)
79+
let claims = try jsonDecoder.decode(T.self, from: claimsData)
7880
self.header = header
7981
self.claims = claims
8082
}

Sources/SwiftJWT/JWTDecoder.swift

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -212,16 +212,18 @@ private struct _JWTKeyedDecodingContainer<Key: CodingKey>: KeyedDecodingContaine
212212
// Those types will be a `Header` object and a generic `Claims` object.
213213
func decode<T : Decodable>(_ type: T.Type, forKey key: Key) throws -> T {
214214
decoder.codingPath.append(key)
215+
let jsonDecoder = JSONDecoder()
216+
jsonDecoder.dateDecodingStrategy = .secondsSince1970
215217
if key.stringValue == "header" {
216-
let header = try JSONDecoder().decode(Header.self, from: self.header)
218+
let header = try jsonDecoder.decode(Header.self, from: self.header)
217219
decoder.keyID = header.kid
218220
guard let decodedHeader = header as? T else {
219221
throw DecodingError.typeMismatch(T.self, DecodingError.Context(codingPath: codingPath, debugDescription: "Type of header key was not a JWT Header"))
220222
}
221223
return decodedHeader
222224
} else
223225
if key.stringValue == "claims" {
224-
return try JSONDecoder().decode(type, from: claims)
226+
return try jsonDecoder.decode(type, from: claims)
225227
} else {
226228
throw DecodingError.keyNotFound(key, DecodingError.Context(codingPath: codingPath, debugDescription: "value not found for provided key"))
227229
}

Sources/SwiftJWT/JWTEncoder.swift

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,8 @@ fileprivate class _JWTEncoder: Encoder {
151151
mutating func encode<T : Encodable>(_ value: T, forKey key: Key) throws {
152152
self.codingPath.append(key)
153153
let fieldName = key.stringValue
154+
let jsonEncoder = JSONEncoder()
155+
jsonEncoder.dateEncodingStrategy = .secondsSince1970
154156
if fieldName == "header" {
155157
guard var _header = value as? Header else {
156158
throw EncodingError.invalidValue(value, EncodingError.Context(codingPath: [], debugDescription: "Failed to encode into header CodingKey"))
@@ -163,10 +165,10 @@ fileprivate class _JWTEncoder: Encoder {
163165
encoder.jwtSigner = keyIDJWTSigner
164166
}
165167
_header.alg = encoder.jwtSigner?.name
166-
let data = try JSONEncoder().encode(_header)
168+
let data = try jsonEncoder.encode(_header)
167169
encoder.header = data.base64urlEncodedString()
168170
} else if fieldName == "claims" {
169-
let data = try JSONEncoder().encode(value)
171+
let data = try jsonEncoder.encode(value)
170172
encoder.claims = data.base64urlEncodedString()
171173
}
172174
}

Tests/SwiftJWTTests/TestJWT.swift

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ let rsaJWTEncoder = JWTEncoder(jwtSigner: .rs256(privateKey: rsaPrivateKey))
2626
let rsaJWTDecoder = JWTDecoder(jwtVerifier: .rs256(publicKey: rsaPublicKey))
2727
let certPrivateKey = read(fileName: "cert_private_key")
2828
let certificate = read(fileName: "certificate")
29-
let rsaEncodedTestClaimJWT = "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJuYW1lIjoiSm9obiBEb2UiLCJhZG1pbiI6dHJ1ZSwic3ViIjoiMTIzNDU2Nzg5MCJ9.WJHaxAjhLu7wkw2J3B7ZpW-pnX-WEDJuy7l46nHZRWtZrH_4f8724v-4V48UlHtEgQpUXCHyGRyWPgPJCdGIfy2vD5GBoMJ1kdNWQa0UVOajTk0omUIloBPKgo-45m3w15ub-_4bihyZOI8dCK9zk5vjvUGnzdKartNi9AN5kNM"
29+
let rsaEncodedTestClaimJWT = "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJuYW1lIjoiSm9obiBEb2UiLCJhZG1pbiI6dHJ1ZSwic3ViIjoiMTIzNDU2Nzg5MCIsImlhdCI6MTUxNjIzOTAyMn0.HbPVSMBtR3l0zyrHIlGRyXkNECgE0RrQreebA2xuIWhN-64MP29-lf8lg5pWKk3gTrnbOxEpek5AvBNgz4VK34enkzhrrMKonBywvZZ8CQtM5FlArgx5ZQqxjD32B7WCqlDOelly1W2rlFNIopBit-OuKBw1ioxQwzDMLb1Ol3Q"
3030
let certificateEncodedTestClaimJWT = "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImtpZCI6IjEifQ.eyJuYW1lIjoiSm9obiBEb2UiLCJhZG1pbiI6dHJ1ZSwic3ViIjoiMTIzNDU2Nzg5MCJ9.CpnzQLuWGfH5Kba36vg0ZZKBnzwlrIgapFVfBfk_nea-eej84ktHZANqIeolskZopRJ4DQ3oaLtHWEg16-ZsujxmkOdiAIbk0-C4QLOVFLZH78WLZAqkyNLS8rFuK9hloLNwz1j6VVUd1f0SOT-wIRzL0_0VRYqQd1bVcCj7wc7BmXENlOfHY7KGHS-6JX-EClT1DygDSoCmdvBExBf3vx0lwMIbP4ryKkyhOoU13ZfSUt1gpP9nZAfzqfRTPxZc_f7neiAlMlF6SzsedsskRCNegW8cg5e_NuVmZZkj0_bnswXFDMmIaxiPdtOEWkmyEOca-EHSwbO5PgCgXOIrgg"
3131
// A `TestClaims` encoded using HMAC with "Super Secret Key" from "www.jwt.io"
3232
let hmacEncodedTestClaimJWT = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJuYW1lIjoiSm9obiBEb2UiLCJhZG1pbiI6dHJ1ZSwic3ViIjoiMTIzNDU2Nzg5MCJ9.8kIE0ZCq1Vw7aW1kACpgJLcgY2DpTXgO6P5T3cdCuTs"
@@ -402,6 +402,7 @@ class TestJWT: XCTestCase {
402402
jwt.claims.sub = "1234567890"
403403
jwt.claims.name = "John Doe"
404404
jwt.claims.admin = true
405+
jwt.claims.iat = Date(timeIntervalSince1970: 1516239022)
405406
do {
406407
let jwtString = try rsaJWTEncoder.encodeToString(jwt)
407408
let decodedJWTString = try JWT<TestClaims>(jwtString: jwtString)
@@ -424,6 +425,7 @@ class TestJWT: XCTestCase {
424425
jwt.claims.sub = "1234567890"
425426
jwt.claims.name = "John Doe"
426427
jwt.claims.admin = true
428+
jwt.claims.iat = Date(timeIntervalSince1970: 1516239022)
427429
do {
428430
let decodedJWT = try rsaJWTDecoder.decode(JWT<TestClaims>.self, fromString: rsaEncodedTestClaimJWT)
429431
jwt.header.alg = "RS256"
@@ -520,6 +522,8 @@ class TestJWT: XCTestCase {
520522
XCTAssertEqual(decoded.claims.sub, "1234567890", "Wrong .sub in decoded")
521523
XCTAssertEqual(decoded.claims.name, "John Doe", "Wrong .name in decoded")
522524
XCTAssertEqual(decoded.claims.admin, true, "Wrong .admin in decoded")
525+
XCTAssertEqual(decoded.claims.iat, Date(timeIntervalSince1970: 1516239022), "Wrong .iat in decoded")
526+
523527

524528
XCTAssertEqual(decoded.validateClaims(), .success, "Validation failed")
525529
}

0 commit comments

Comments
 (0)