【问题标题】:Swift 3.0 token expire how will be call the token automatically?Swift 3.0 令牌过期如何自动调用令牌?
【发布时间】:2018-02-12 08:14:12
【问题描述】:

一旦收到token,当token结束时,如何登录后自动调用token?在同一页面上

 Alamofire.request(urlString, method: .post, parameters: newPost, encoding: JSONEncoding.default)
        .responseJSON { response in

            if let json = response.result.value as? [String : Any]{
                print("JSON: \(json)")
                if UserDefaults.standard.bool(forKey: "logged_in") {

                    Token = json["Token"]! as! String

                    UserDefaults.standard.set(Token, forKey: "Token")
                    UserDefaults.standard.synchronize()

                }

            } else {
                print("Did not receive json")
            }

            //expectation.fulfill()
    }

【问题讨论】:

  • 您可以为所有请求创建自己的方法(所有调用都应使用此方法完成),当您发现错误是由于令牌无效时,重做令牌调用,并成功,重做之前的请求。?
  • 创建一个函数并在需要时调用
  • @BHAVIKPANCHAL 任何相关的示例令牌?
  • 你是在userdefault中设置的,然后你可以在登录后或通过userdefault获得的任何其他屏幕获取令牌。
  • userdefault.standard.object(forkey:"token");

标签: ios swift token access-token


【解决方案1】:

场景 1: 您需要告诉创建您的 web 服务的后端开发人员,他需要检查 TOKEN 是否有效。如果令牌已过期,他需要提供消息代码或“令牌已过期”的消息,如果消息代码已过期,您可以在响应中检查,而不是导航您的登录屏幕。 这是最佳实践。

场景 2: 如果您不想从应用程序中注销,并让应用程序继续使用新令牌自动刷新,请告诉 Web 服务开发人员,每当令牌过期时,他将在响应字段中返回新令牌“授权”并且从您的代码方面,您需要在每个请求中检查授权是否包含新令牌。如果它包含这意味着您需要在 userdefault 中将旧令牌替换为新令牌。

以下是我在 Swift3 中的代码:

func requestApiCall(_ urlString: String, paramData: NSObject, completionHandler: @escaping (NSDictionary?, NSError?) -> ()) {
    let token =   UserDefaults.standard.object(forKey: “token” as String)
    var headersVal = [
        "Authorization": "Bearer "+(token as String),
    ]      
 Alamofire.request(urlString, method: .post, parameters: paramData as? [String : AnyObject],encoding: JSONEncoding.default, headers: headersVal)

        .responseJSON { response in
            if let authorization = response.response?.allHeaderFields["Authorization"] as? String {

                var newToken : String = authorization
                UserDefaults.standard.set(newToken, forKey: "token")
                UserDefaults.standard.synchronize()
            }

            switch response.result {

            case .success(let value):

              if let res = response.result.value {
                     let response = res as! NSDictionary
                     let message = response.object(forKey: "message")!
                     print(message)
                if message as! String ==  "Token has been expired" 
                {
                    self.showLoginScreen()
                }
              }
            completionHandler(value as? NSDictionary, nil)

            case .failure(let error):
                if error._code == -1001 {
                    print("timeout")
                }
                completionHandler(nil, nil)
            }
      }
}

【讨论】:

  • 如果 res[“message”].string == "Token has been expired",则字符串不能工作
  • 你可以转换成 NSDictionary like : let response = res as! NSDictionary let message = response.object(forKey: "message")! print(message) if message as! String == "Token has been expired" { self.showLoginScreen() } } 确保你使用我使用的正确密钥“消息”
  • @foram n 天后用户打开应用程序是什么&在仪表板上存在 4 个并发服务调用&服务提供令牌已过期。在这种情况下如何处理所有 API?
【解决方案2】:

对于Authorisation Token,理想的做法是从服务器端他们需要检查,请求的API调用有TOKEN是否有效。如果令牌不匹配或过期,他们将提供HTTP status code401,从移动端你需要先检查状态码,如果你发现401你需要强制注销或重新登录,这需要一个新的令牌,您可以将其保存在您的UserDefaults

【讨论】:

    【解决方案3】:

    我更喜欢将Moya 框架(Alamofire 下的抽象)与PromiseKit 一起使用。它使编写异步代码和创建部件之间的依赖关系变得更加容易。我将用于发送请求的所有业务逻辑包装在类中。请求的主函数(public func register(device: String, type: String) -> Promise<Device>)返回Promise对象。在recover 块中,我验证错误代码,如果需要,我刷新令牌并重复失败的请求。下面的代码示例:

    public protocol HttpClientInterface {
    ...
        func register(device: String, type: String) -> Promise<Device>
    ...
    }
    
    public func register(device: String, type: String) -> Promise<Device> {
        return self.sendRegisterRequest(with: device, type: type)
            .then {
                self.parseRegister(response: $0)
            }
            .recover { lerror -> Promise<Device> in
                guard let error = lerror as? HttpClientError,
                    case .server(let value) = error,
                    value == ServerError.notAuthenticated,
                    let refreshToken = self.credentialsStore.get()?.token?.refreshToken else {
                        throw lerror
                }
    
                return self.sendRefreshSessionRequest(operatorId: self.operatorId, refreshToken: refreshToken)
                    .then { data -> Promise<AuthToken> in
                        return self.parseRefreshSession(data)
                    }
                    .then { token -> Promise<Device> in
                        self.credentialsStore.update(token: token)
                        return self.register(device: device, type: type)
                    }
                    .catch { error in
                        if let myError = error as? HttpClientError,
                            case .server(let value) = httpError,
                            value == ServerError.notAuthenticated {
                            self.credentialsStore.accessDenied()
                        }
                }
        }
    }
    
    func sendRegisterRequest(with name: String, type: String) -> Promise<Data> {
        return Promise { fulfill, reject in
            self.client.request(.register(device: name, type: type)) {
                self.obtain(result: $0,
                            successStatusCodes: [200, 201],
                            fulfill: fulfill,
                            reject: reject)
            }
        }
    }
    
    func parseRegister(response data: Data) -> Promise<Device> {
        return Promise { fulfill, reject in
            if let account = Account(data: data),
                let device = account.devices?.last {
                fulfill(device)
            } else {
                reject(HttpClientError.internalError())
            }
        }
    }
    

    【讨论】:

      【解决方案4】:

      令牌过期时为新令牌调用服务对您的应用来说是不安全的,因为如果令牌过期并且您为新令牌调用服务,那么任何人都可以访问您的应用或其数据。更好的方法是注销/退出用户并要求他再次登录。

      但如果您想这样做,请创建一个方法,即用户获取新令牌并在您获得令牌过期代码后调用它。

      但是您需要与您的后端开发人员讨论这个新的 api,因此您可以走得更远

      让我知道以寻求帮助。谢谢

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2016-09-10
        • 2020-11-11
        • 1970-01-01
        • 1970-01-01
        • 2015-05-10
        • 2017-06-13
        • 2021-10-22
        • 1970-01-01
        相关资源
        最近更新 更多