从JWT获取用户ID(JSON Web令牌)

时间:2019-03-28 04:48:32

标签: json swift jwt

我正在使用该插件通过api-rest来验证WordPress:JWT Authentication for WP REST API

从请求到服务器,我得到以下答案:

{
    "token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJodHRwczpcL1wvbWlob3N0Lm9yZ1wvcHJ1ZWJhcyIsImlhdCI6MTU1MzcyNDM4MSwibmJmIjoxNTUzNzI0MzgxLCJleHAiOjE1NTQzMjkxODEsImRhdGEiOnsidXNlciI6eyJpZCI6IjIifX19.rgi5Q2c8RCoHRp-lJiJN8xQaOavn9T_q8cmf8v1-57o",
    "user_email": "abc@test.com",
    "user_nicename": "test",
    "user_display_name": "Test"
}

到目前为止,一切正常,但是我需要知道用户ID。

我已经阅读到令牌是在base64中编码的,并且在其中是ID。尝试解码时,我看到所需的ID是否存在。

我很快就使用此功能对令牌进行解码,但无法获取字典ID。

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
}

返回此函数的字典为:

["iss": https://myhost.me/test, "exp": 1554235730, "nbf": 1553630930, "iat": 1553630930, "data": {
    user =     {
        id = 2;
    };
}]

如何从该词典中获取ID?

1 个答案:

答案 0 :(得分:3)

您的代码很简单。

如果存在本机等效项,并且JSON字典始终是值类型(NS...),则在Swift中基本上不使用[String:Any]类。

我建议添加一个Error枚举,使函数可以抛出,用Decodable解码序列化的令牌,并在成功后返回Token实例< / p>

struct Token : Decodable {
    let data : UserData

    struct UserData  : Decodable {
        let user : User

        struct User  : Decodable {
            let id : String
        }
    }
}

鼓励您将参数标签保留在方法声明中

enum TokenError : Error {
    case invalidJWTFormat, invalidBase64EncodedData
}

func decode(token: String) throws -> Token {
    let components = token.components(separatedBy: ".")
    guard components.count == 3 else { throw TokenError.invalidJWTFormat }
    var decodedString = components[1]
        .replacingOccurrences(of: "-", with: "+")
        .replacingOccurrences(of: "_", with: "/")

    while decodedString.utf16.count % 4 != 0 { 
        decodedString += "=" 
    }
    guard let decodedData = Data(base64Encoded: decodedString) else { throw TokenError.invalidBase64EncodedData }
    return try JSONDecoder().decode(Token.self, from: decodedData)
}

并调用它

do {
   let userID = try decode(token: "eyJ0eXAi.....").data.user.id
} catch { print(error) }