Как только токен получен, когда токен закончен, как я могу вызвать токен автоматически после входа в систему? на той же странице
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()
}
4 ответа
Сценарий 1: вам нужно сообщить бэкэнд-разработчику, который создал ваш веб-сервис, что ему нужно проверить, действителен ли TOKEN или нет. если срок действия токена истек, ему нужно указать код сообщения или сообщение о том, что «токен истек», и вы можете проверить в ответе, истек ли срок действия кода сообщения, чем вам нужно перемещаться по экрану входа в систему. Это лучшая практика.
Сценарий 2 . Если вы не хотите выходить из приложения и продолжать обновлять приложение с новым токеном, сообщите разработчику веб-службы, что при истечении срока действия токена он будет возвращать новый токен в поле ответа как «Авторизация». И со стороны вашего кода, вы должны проверять в каждом запросе, содержит ли Authorization новый токен ... если он содержит, это означает, что вам нужно заменить старый токен на New в 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)
}
}
}
Для Authorisation Token
идеальной практикой является проверка на стороне сервера, запрашиваемый вызов API имеет TOKEN
, действителен или нет. И если токен не найден или не имеет срока действия, он предоставит HTTP status code
401
, со стороны мобильной связи сначала необходимо проверить код состояния, а если вы обнаружили 401
, вам необходимо принудительно выйти из системы или Войдите в систему, чтобы получить новый токен, и вы можете сохранить его в своем UserDefaults
.
Служба вызова для нового токена по истечении срока действия токена является небезопасной для вашего приложения, поскольку, если срок действия токена истекает и вы вызываете службу для получения нового токена, любой может получить доступ к вашему приложению или его данным. Лучший способ - выйти из системы и выйти из системы и попросить его снова войти в систему.
Но если вы хотите сделать это, то создайте метод user, чтобы получить новый токен, и вызовите его, как только вы получите код истечения токена.
Но вы должны обсудить с вашим бэкэнд-разработчиком этот новый API и, соответственно, вы можете двигаться дальше
Дайте мне знать о помощи. Спасибо
Я предпочел использовать Moya
framework (абстракция под 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())
}
}
}
Похожие вопросы
Новые вопросы
ios
iOS - мобильная операционная система, работающая на Apple iPhone, iPod touch и iPad. Используйте этот тег [ios] для вопросов, связанных с программированием на платформе iOS. Используйте связанные теги [target-c] и [swift] для проблем, характерных для этих языков программирования.