Skip to content

Instantly share code, notes, and snippets.

@davbeck
Last active March 1, 2019 21:47
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save davbeck/43cb49b250512e8e30612ba4a69b2eb3 to your computer and use it in GitHub Desktop.
Save davbeck/43cb49b250512e8e30612ba4a69b2eb3 to your computer and use it in GitHub Desktop.
A basic JWT parser for Swift that doesn't do any validation.
import Foundation
extension Data {
/// JWT strips the padding off the end of the base64 string
fileprivate init?(jwtPart: String) {
var paddingCount = 4 - jwtPart.count % 4
if paddingCount == 4 {
paddingCount = 0
}
let padding = String(repeating: "=", count: paddingCount)
self.init(base64Encoded: jwtPart + padding)
}
}
// this is a very simplified JWT parser that does not do any actual validation
// we just want to pull the expiration data out of our tokens
// the services will actually validate these
struct JWT {
enum Error: Swift.Error {
case wrongNumberOfComponents
case invalidBase64Content
}
var header: Data
var payload: Data
var signiture: String
init(_ token: String) throws {
let parts = token.components(separatedBy: ".")
guard parts.count == 3 else { throw Error.wrongNumberOfComponents }
guard let header = Data(jwtPart: parts[0]) else { throw Error.invalidBase64Content }
self.header = header
guard let payload = Data(jwtPart: parts[1]) else { throw Error.invalidBase64Content }
self.payload = payload
signiture = parts[2]
}
}
struct JWTPayload: Codable {
var iat: Date
var exp: Date
func isValid() -> Bool {
return exp.timeIntervalSinceNow > 0
}
public init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
iat = try Date(timeIntervalSince1970: container.decode(TimeInterval.self, forKey: .iat))
exp = try Date(timeIntervalSince1970: container.decode(TimeInterval.self, forKey: .exp))
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment