【问题标题】:Checking if Auth0 idToken has expired检查 Auth0 idToken 是否已过期
【发布时间】:2018-02-11 00:29:21
【问题描述】:

我有一个 Swift 应用程序,它实现了 Auth0 的 Web 登录。成功登录后,我会收到一个 access tokenidToken,它们都本地存储在我的 Keychain 中。下次登录时,我首先检查访问令牌(存储在钥匙串中)是否仍然有效

Auth0
     .authentication()
     .userInfo(withAccessToken: accessToken)
     .start { result in
         switch result {
         case .success(result: let profile):

             print("access token still valid")

成功后不必再次登录。然而,我遇到的问题是,我的 idToken 可能已经过期,即使我的访问令牌仍然有效,这会在我使用这个 idToken 请求我的(GraphQL)后端时导致错误。那么我该如何解决呢?有没有办法检查我的 idToken 是否在 Swift 中过期?因为如果没有办法检查,我将不得不要求登录,即使令牌可能未过期。那没有意义。

【问题讨论】:

    标签: ios swift auth0


    【解决方案1】:

    idToken 是 JSON Web Token (JWT),因此元数据是可读的。要查看它的外观,请将您的令牌粘贴到 jwt.io 并查看格式。

    以这个 JWT 为例:

    eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiZXhwIjoiMTUwNDc1MzQ0NSIsImFkbWluIjp0cnVlfQ.ggeW2vGcdWKNWmICRfTZ8qcBOQlu38DzaO8t_6aNuHQ
    

    它分为 3 部分:标头、有效负载和签名。过期时间在有效负载部分。

    我们只需要对它进行base64解码。

    let jwt = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvbiBTbm93IiwiZXhwIjoiMTUwNDc1MzQ0NSIsImFkbWluIjp0cnVlfQ.aCiqyVAAmHizPshrcdy8jwgHvBg4Diz2YY2e1INjoPg"
    
    // get the payload part of it
    var payload64 = jwt.components(separatedBy: ".")[1]
    
    // need to pad the string with = to make it divisible by 4,
    // otherwise Data won't be able to decode it
    while payload64.count % 4 != 0 {
        payload64 += "="
    }
    
    print("base64 encoded payload: \(payload64)")
    let payloadData = Data(base64Encoded: payload64,
                           options:.ignoreUnknownCharacters)!
    let payload = String(data: payloadData, encoding: .utf8)!
    print(payload)
    

    打印出来:

    {"sub":"1234567890","name":"Jon Snow","exp":"1504753445","admin":true}
    

    exp 是您的到期日期。您可以将其传递给 JSON 序列化程序以获取日期:

    let json = try! JSONSerialization.jsonObject(with: payloadData, options: []) as! [String:Any]
    let exp = json["exp"] as! Int
    let expDate = Date(timeIntervalSince1970: TimeInterval(exp))
    let isValid = expDate.compare(Date()) == .orderedDescending
    

    【讨论】:

    • 非常感谢,帮了大忙!
    • @Ben Scheirman:如果用户在“设置”中更改操作系统时间,这种方式是否会受到影响?
    • @Bad_Developer 客户端检查实际上只是为了知道您是否应该刷新。服务器仍将验证这一点,并以 401 响应拒绝令牌。所以你需要处理这两种情况。在我的应用程序中,当令牌过期(或即将过期)时,我会先主动刷新令牌以避免收到 401。
    猜你喜欢
    • 2019-07-23
    • 2017-08-15
    • 2021-12-21
    • 2017-05-31
    • 2010-10-26
    • 1970-01-01
    • 2019-12-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多