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() 确保你使用我使用的正确密钥“消息” @foramn
天后用户打开应用程序是什么&在仪表板上存在 4 个并发服务调用&服务提供令牌已过期。在这种情况下如何处理所有 API?【参考方案2】:
对于Authorisation Token
,理想的做法是从服务器端他们需要检查,请求的API调用有TOKEN
是否有效。如果令牌不匹配或过期,他们将提供HTTP status code
401
,从移动端你需要先检查状态码,如果你发现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 令牌过期如何自动调用令牌?的主要内容,如果未能解决你的问题,请参考以下文章
如果 Firebase 令牌在 React 应用程序中过期,如何不调用任何 api 端点?