Получить идентификатор пользователя из JWT (веб-токен JSON) - PullRequest
1 голос
/ 28 марта 2019

Я использую плагин для аутентификации WordPress с помощью api-rest: Аутентификация JWT для WP REST API

От запроса к серверу я получаю следующий ответ:

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

Пока все работает нормально, но мне нужно знать идентификатор пользователя.

Я прочитал, что токен закодирован в base64, и внутри него есть идентификатор. Пытаясь декодировать, я вижу, есть ли нужный мне идентификатор.

В swift с этой функцией я декодирую токен, но не могу получить идентификатор словаря.

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;
    };
}]

Как мне получить идентификатор из этого словаря?

1 Ответ

3 голосов
/ 28 марта 2019

Ваш код довольно не изменен .

Как правило, не используйте NS... классы в Swift, если есть собственный эквивалент, и словарь JSON всегда имеет тип значения ([String:Any]).

Я рекомендую добавить перечисление Error, сделать так, чтобы функция могла выбросить , декодировать сериализованный токен с помощью Decodable и вернуть экземпляр Token в случае успеха

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) }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...