trying to decode a JWT payload in Swift and having a really difficult time
static func decodePayload(tokenstr: String) {
//splitting JWT to extract payload
let arr = split(tokenstr) {$0 == "."}
//base64 encoded string i want to decode
let base64String = arr[1] as String
println(base64String) //eyJleHAiOjE0MjY4MjIxNjMsImlkIjoiNTUwYjA3NzM4ODk1NjAwZTk5MDAwMDAxIn0
//attempting to convert base64 string to nsdata
let nsdata: NSData = NSData(base64EncodedString: base64String, options: NSDataBase64DecodingOptions(rawValue: 0))
//decoding fails because nsdata unwraps as nil
let base64Decoded: NSString = NSString(data: nsdata!, encoding: NSUTF8StringEncoding)!
}
By design, anyone can decode a JWT and read the contents of the header and payload sections. But we need access to the secret key used to create the signature to verify a token's integrity.
eyJleHAiOjE0MjY4MjIxNjMsImlkIjoiNTUwYjA3NzM4ODk1NjAwZTk5MDAwMDAxIn0
is not a valid Base64 encoded string because its length
is not a multiple of 4. Some Base64 decoder tolerate this error, but
the NSData
methods don't.
So this is actually an error on the server side creating the
Base64 encoded string. If necessary, you can fix it in your app
by adding the required padding with =
characters (code updated for Swift 2):
var base64String = arr[1] as String
if base64String.characters.count % 4 != 0 {
let padlen = 4 - base64String.characters.count % 4
base64String += String(count: padlen, repeatedValue: Character("="))
}
And now the decoding works as expected:
if let data = NSData(base64EncodedString: base64String, options: []),
let str = String(data: data, encoding: NSUTF8StringEncoding) {
print(str) // {"exp":1426822163,"id":"550b07738895600e99000001"}
}
Swift 4:
var base64String = "eyJleHAiOjE0MjY4MjIxNjMsImlkIjoiNTUwYjA3NzM4ODk1NjAwZTk5MDAwMDAxIn0"
if base64String.count % 4 != 0 {
let padlen = 4 - base64String.count % 4
base64String.append(contentsOf: repeatElement("=", count: padlen))
}
if let data = Data(base64Encoded: base64String) ,
let str = String(data: data, encoding: .utf8) {
print(str) // {"exp":1426822163,"id":"550b07738895600e99000001"}
}
Above solution is working for me, I converted into swift3
Here you can find swift3 code
var base64Str = arr[1] as String
if base64Str.characters.count % 4 != 0 {
let padlen = 4 - base64Str.characters.count % 4
base64Str += String(repeating: "=", count: padlen)
}
if let data = Data(base64Encoded: base64Str, options: []),
let str = String(data: data, encoding: String.Encoding.utf8) {
print(str)
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With