2015-03-19 13 views
7

versucht, eine JWT Nutzlast in Swift zu dekodieren und eine wirklich schwierige ZeitDekodieren von JSON Web Tokens in Swift

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)! 


} 

Antwort

14
eyJleHAiOjE0MjY4MjIxNjMsImlkIjoiNTUwYjA3NzM4ODk1NjAwZTk5MDAwMDAxIn0 

ist keine gültige Base64-codierte Zeichenfolge, weil seine Länge nicht ein Vielfaches von 4 ist Einige Base64-Decoder tolerieren diesen Fehler, aber die NSData Methoden nicht.

Das ist also tatsächlich ein Fehler auf der Server-Seite, die Base64-codierte Zeichenfolge erstellt. Falls erforderlich, können Sie es beheben in Ihrer App , indem Sie die erforderlichen Polsterung mit = Zeichen (Code aktualisiert 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("=")) 
} 

Und nun die Decodierung wie erwartet funktioniert:

if let data = NSData(base64EncodedString: base64String, options: []), 
    let str = String(data: data, encoding: NSUTF8StringEncoding) { 
    print(str) // {"exp":1426822163,"id":"550b07738895600e99000001"} 
} 
+0

wo genau sollte als Best Practice gespeichert werden JWT Token? Ich habe gedacht, dass es zusammen mit Benutzername und Passwort im Schlüsselbund gespeichert werden sollte. – user805981

+0

@ user805981: Ich weiß eigentlich nichts über JWT Token. Aber ja, sensible Daten wie Passwörter sollten im Schlüsselbund gespeichert werden. –

+0

Danke. In Bezug auf Schlüsselanhänger. Wie viele Keychain-Wörterbücher kann der Keychain pro App speichern? Ist es unbegrenzt oder ein Passwort Keychain pro App? – user805981

4

Above Lösung wird für mich arbeiten, konvertiert ich in swift3

Hier können Sie 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) 
} 
finden
-1

Swift 4 wie folgt:

if let data = Data(base64Encoded: base64String, options: []), 
     let str = String(data: data as Data, encoding: String.Encoding.utf8) { 
     print(str) // {"exp":1426822163,"id":"550b07738895600e99000001"} 
    } 
+1

In Swift 4 ist es besser, Daten als NSData zu verwenden (und viel besser Daten zu verwenden als NSData in Daten zu konvertieren). Und * sowieso *, Update für Swift 3+ wurde bereits von @ raju-abe in ihrer Antwort gegeben. Bitte posten Sie keine doppelten/unvollständigen Inhalte. – Moritz