Swift 3.0 令牌过期如何自动调用令牌?

Posted

技术标签:

【中文标题】Swift 3.0 令牌过期如何自动调用令牌?【英文标题】:Swift 3.0 token expire how will be call the token automatically? 【发布时间】: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"); 【参考方案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,因此您可以走得更远

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

【讨论】:

以上是关于Swift 3.0 令牌过期如何自动调用令牌?的主要内容,如果未能解决你的问题,请参考以下文章

如何知道访问令牌已过期?

如何在jwt中过期时刷新令牌

如果 Firebase 令牌在 React 应用程序中过期,如何不调用任何 api 端点?

GCM 3.0:新注册不会过期使用 GCMRegistrar 注册的令牌

jwt令牌过期后如何注销

提供的 Facebook 会话令牌已过期或无效