web-dev-qa-db-fra.com

Comment puis-je décoder le jeton JWT (jeton Web JSON) dans Swift?

J'ai un jeton JWT comme celui-ci

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95HHF7

Comment puis-je décoder cela afin que je puisse obtenir la charge utile comme celle-ci

{"sub": "1234567890", "name": "John Doe", "admin": true}

12

Si vous êtes d'accord avec l'utilisation d'une bibliothèque, je suggère ceci https://github.com/auth0/JWTDecode.Swift

puis importez la bibliothèque import JWTDecode et exécutez.

let jwt = try decode(jwt: token)

Comme vous ne vouliez pas inclure cette bibliothèque, j'ai sorti les pièces nécessaires pour le faire fonctionner.

func decode(jwtToken jwt: String) -> [String: Any] {
  let segments = jwt.components(separatedBy: ".")
  return decodeJWTPart(segments[1]) ?? [:]
}

func base64UrlDecode(_ value: String) -> Data? {
  var base64 = value
    .replacingOccurrences(of: "-", with: "+")
    .replacingOccurrences(of: "_", with: "/")

  let length = Double(base64.lengthOfBytes(using: String.Encoding.utf8))
  let requiredLength = 4 * ceil(length / 4.0)
  let paddingLength = requiredLength - length
  if paddingLength > 0 {
    let padding = "".padding(toLength: Int(paddingLength), withPad: "=", startingAt: 0)
    base64 = base64 + padding
  }
  return Data(base64Encoded: base64, options: .ignoreUnknownCharacters)
}

func decodeJWTPart(_ value: String) -> [String: Any]? {
  guard let bodyData = base64UrlDecode(value),
    let json = try? JSONSerialization.jsonObject(with: bodyData, options: []), let payload = json as? [String: Any] else {
      return nil
  }

  return payload
}

Appelez ça comme ceci:

decode(jwtToken: TOKEN)
28
Viktor Gardart
    func decode(_ token: String) -> [String: AnyObject]? {
    let string = token.components(separatedBy: ".")
    let toDecode = string[1] as String


    var stringtoDecode: String = toDecode.replacingOccurrences(of: "-", with: "+") // 62nd char of encoding
    stringtoDecode = stringtoDecode.replacingOccurrences(of: "_", with: "/") // 63rd char of encoding
    switch (stringtoDecode.utf16.count % 4) {
    case 2: stringtoDecode = "\(stringtoDecode)=="
    case 3: stringtoDecode = "\(stringtoDecode)="
    default: // nothing to do stringtoDecode can stay the same
        print("")
    }
    let dataToDecode = Data(base64Encoded: stringtoDecode, options: [])
    let base64DecodedString = NSString(data: dataToDecode!, encoding: String.Encoding.utf8.rawValue)

    var values: [String: AnyObject]?
    if let string = base64DecodedString {
        if let data = string.data(using: String.Encoding.utf8.rawValue, allowLossyConversion: true) {
            values = try! JSONSerialization.jsonObject(with: data, options: JSONSerialization.ReadingOptions.allowFragments) as? [String : AnyObject]
        }
    }
    return values
}
5
clopex

J'ai la solution pour ça.

 static func getJwtBodyString(tokenstr: String) -> NSString {

    var segments = tokenstr.components(separatedBy: ".")
    var base64String = segments[1]
    print("\(base64String)")
    let requiredLength = Int(4 * ceil(Float(base64String.characters.count) / 4.0))
    let nbrPaddings = requiredLength - base64String.characters.count
    if nbrPaddings > 0 {
        let padding = String().padding(toLength: nbrPaddings, withPad: "=", startingAt: 0)
        base64String = base64String.appending(padding)
    }
    base64String = base64String.replacingOccurrences(of: "-", with: "+")
    base64String = base64String.replacingOccurrences(of: "_", with: "/")
    let decodedData = Data(base64Encoded: base64String, options: Data.Base64DecodingOptions(rawValue: UInt(0)))
  //  var decodedString : String = String(decodedData : nsdata as Data, encoding: String.Encoding.utf8)

    let base64Decoded: String = String(data: decodedData! as Data, encoding: String.Encoding(rawValue: String.Encoding.utf8.rawValue))!
    print("\(base64Decoded)")
    return base64String as NSString
}

Cela fonctionne très bien pour moi. Je vous remercie.

Il y a une implémentation Swift. Ajoutez ceci dans votre Podfile si vous utilisez CocoaPods ou clonez le projet et utilisez-le directement.

JSONWebToken

do {
  // the token that will be decoded
  let token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ"
  let payload = try JWT.decode(token, algorithm: .hs256("secret".data(using: .utf8)!))
  print(payload)
} catch {
  print("Failed to decode JWT: \(error)")
}
2
Ch0k0l8

Si vous souhaitez utiliser une bibliothèque pour cela, je vous recommande d'utiliser quelque chose de populaire auprès d'une personne grande. IBM crée Kitura - Swift framework backend, donc l'implémentation du codage et du décodage JWT pour cela doit être de premier ordre:

Lien: https://github.com/IBM-Swift/Swift-JWT

Utilisation simple du token avec date d'expiration

import SwiftJWT

struct Token: Decodable {
    let jwtString: String

    func abc() {

        do {
            let newJWT = try JWT<MyJWTClaims>(jwtString: jwtString)
            print(newJWT.claims.exp)
        } catch {
            print("OH NOES")
        }


    }
}

struct MyJWTClaims: Claims {
    let exp: Date
}
1
vol

Itération sur le code de Viktor:

  • Je ne savais pas pourquoi il y avait des remplacements pour - et _ je n'ai vu cela dans aucun de mes jetons.
  • Utilisez des fonctions imbriquées pour rester plus modulaire
  • Utilisez les exceptions en cas de passage d'un mauvais jeton ou d'autres erreurs.
  • Calcul plus simple du rembourrage et utilisation de la fonction de rembourrage.

J'espère que c'est utile:

func decode(jwtToken jwt: String) throws -> [String: Any] {

    enum DecodeErrors: Error {
        case badToken
        case other
    }

    func base64Decode(_ base64: String) throws -> Data {
        let padded = base64.padding(toLength: ((base64.count + 3) / 4) * 4, withPad: "=", startingAt: 0)
        guard let decoded = Data(base64Encoded: padded) else {
            throw DecodeErrors.badToken
        }
        return decoded
    }

    func decodeJWTPart(_ value: String) throws -> [String: Any] {
        let bodyData = try base64Decode(value)
        let json = try JSONSerialization.jsonObject(with: bodyData, options: [])
        guard let payload = json as? [String: Any] else {
            throw DecodeErrors.other
        }
        return payload
    }

    let segments = jwt.components(separatedBy: ".")
    return try decodeJWTPart(segments[1])
  }
1
possen