2015-03-19 8 views
7

cercando di decodificare un payload JWT a Swift e avendo un momento davvero difficiledecodifica JSON Web Gettoni a 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)! 


} 

risposta

14
eyJleHAiOjE0MjY4MjIxNjMsImlkIjoiNTUwYjA3NzM4ODk1NjAwZTk5MDAwMDAxIn0 

non è un Base64 stringa codificata valido perché la sua lunghezza non è un multiplo di 4 Alcuni decoder Base64 tollerano questo errore, ma i metodi non lo sono.

Quindi questo è in realtà un errore sul lato server che crea la stringa codificata Base64 . Se necessario, è possibile risolvere il problema nella vostra applicazione aggiungendo l'imbottitura richiesto con = caratteri (codice aggiornati per 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("=")) 
} 

E ora la decodifica funziona come previsto:

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

esattamente dove dovrebbero JWT gettoni essere archiviati come best practice? Ho pensato che dovrebbe essere memorizzato in portachiavi con nome utente e password. – user805981

+0

@ user805981: In realtà non so nulla dei token jwt. Ma sì, i dati sensibili come le password dovrebbero essere memorizzati nel portachiavi. –

+0

Grazie. Per quanto riguarda i portachiavi. Quanti dizionari di portachiavi è il portachiavi in ​​grado di memorizzare per app? È un portachiavi infinito o una password per app? – user805981

4

Sopra la soluzione sta lavorando per me, ho convertito in swift3

Qui potete trovare il codice swift3

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) 
} 
-1

Swift 4 come di seguito:

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 è meglio utilizzare Data rispetto a NSData (e il modo migliore per utilizzare Data piuttosto che trasmettere NSData ai dati). E * comunque *, l'aggiornamento per Swift 3+ è già stato dato da @ raju-abe nella loro risposta. Si prega di non pubblicare contenuti duplicati/incompleti. – Moritz