Reputation: 2035
i have a swift application which uses API for authentication everything works fine and when users logout, the login token is supposed to get cleared so that the new user's details can be collected and the new Token passed into the header but i noticed that when I try login in another user, the previous users token remains in the header and thereby preventing the new user from login in. I clear the login values on logout button pressed but i have no idea why the token value remains in the header. my codes are shown below
let defaults = UserDefaults.standard
var isLoggedIn : Bool {
get {
return defaults.bool(forKey: LOGGED_IN_KEY)
}
set {
defaults.set(newValue, forKey: LOGGED_IN_KEY)
}
}
var authToken: String {
get {
return defaults.value(forKey: TOKEN_KEY) as? String ?? ""
}
set {
defaults.set(newValue, forKey: TOKEN_KEY)
}
}
var userUsername: String {
get {
return defaults.value(forKey: USER_USERNAME) as? String ?? ""
}
set {
defaults.set(newValue, forKey: USER_USERNAME)
}
}
//MARK :- LOGGIN
func findUserByUserName(completion: @escaping CompletionHandler) -> Void {
Alamofire.request(URL_USER_BY_USERNAME, method: .get, parameters: nil, encoding: JSONEncoding.default, headers: TOKEN_HEADER).validate().responseJSON { (response) in
print("URL USER BY HEADER \(self.authToken)")
if response.result.error == nil {
guard let data = response.data else {return}
let jsonString = String(data: data, encoding: .utf8)
print(jsonString as Any)
self.setUserInfo(data: data)
completion(true)
}
else {
completion(false)
debugPrint("ERROR 22222\(response.result.error as Any)")
}
}
}
func setUserInfo(data: Data) -> Void {
do {
let json = try JSON(data: data)
let pk = json["pk"].intValue
let username = json["username"].stringValue
let email = json["email"].stringValue
let firstName = json["first_name"].stringValue
let lastName = json["last_nameme"].stringValue
print("THE USERNAME IZZZZ \(username)")
UserDataService.instance.setUserData(pk: pk, username: username, email: email, firstName: firstName, lastName: lastName)
} catch {
print(error)
}
func loginUser(email: String, password: String, completion: @escaping CompletionHandler) -> Void {
let usernameEmail = email.lowercased()
let body: [String: Any] = [
"username": usernameEmail,
"email": "",
"password": password,
]
Alamofire.request(URL_LOGIN, method: .post, parameters: body, encoding: JSONEncoding.default, headers: HEADER).validate().responseJSON { (response) in
if response.result.error == nil {
print("LOGIN SUCCESFULL \(self.authToken)")
do {
guard let data = response.data else {return}
let jsonString = String(data: data, encoding: .utf8)
print("HELLOOO \(jsonString as Any)")
let json = try JSON(data: data)
self.authToken = json["key"].stringValue
self.userUsername = email
self.isLoggedIn = true
completion(true)
print("LOGIN SUCCESFULL TOKEN1111 \(self.authToken)")
} catch {
print("errorrrrr")
}
} else {
completion(false)
debugPrint("ERROR YENNNNN \(response.result.error as Any)")
}
}
}
//MARK :- LOGGIN
func findUserByEmail(completion: @escaping CompletionHandler) -> Void {
let body: [String: Any] = [
"username": AuthService.instance.userUsername,
]
Alamofire.request(URL_USER_BY_EMAIL, method: .put, parameters: body, encoding: JSONEncoding.default, headers: TOKEN_HEADER).validate().responseJSON { (response) in
print("URL USER BY HEADER \(self.authToken)")
if response.result.error == nil {
guard let data = response.data else {return}
print("USERUSERNAME \(self.authToken)")
let jsonString = String(data: data, encoding: .utf8)
print(jsonString as Any)
self.setUserInfo(data: data)
completion(true)
}
else {
completion(false)
debugPrint("ERROR 22222\(response.result.error as Any)")
}
}
}
Token Constant
let TOKEN_HEADER = [
"Authorization": "Token \(AuthService.instance.authToken)",
"Content-Type": "application/json; charset=utf-8"
]
UserService
func setUserData(pk: Int, username: String, email: String, firstName: String, lastName: String) -> Void {
self.pk = pk
self.username = username
self.email = email
self.firstName = firstName
self.lastName = lastName
}
func logoutUser() -> Void {
self.pk = 0
self.username = ""
self.email = ""
self.firstName = ""
self.lastName = ""
AuthService.instance.isLoggedIn = false
AuthService.instance.authToken = ""
AuthService.instance.userUsername = ""
}
Logout
@IBAction func logoutPressed(_ sender: Any) {
UserDataService.instance.logoutUser()
print("LOGOUT TOKEN \(AuthService.instance.authToken)")
UserDataService.instance.setUserData(pk: 0, username: "", email: "", firstName: "", lastName: "")
AuthService.instance.authToken = ""
NotificationCenter.default.post(name: NOTIFY_USER_DATA_DID_CHANGE, object: nil)
dismiss(animated: true, completion: nil)
}
further codes would be supplied on request
Upvotes: 0
Views: 722
Reputation: 100543
The problem is you think that whenever you call TOKEN_HEADER
you get the lastest value from
let TOKEN_HEADER = [
"Authorization": "Token \(AuthService.instance.authToken)",
"Content-Type": "application/json; charset=utf-8"
]
but this doesn't happen as the variable get it's value from first initialization whatever the token value was , so you have to refactor sending the the header to Alamofire
, by hardcoding the string again like this
func findUserByUserName(completion: @escaping CompletionHandler) -> Void {
let updated_HEADER = [
"Authorization": "Token \(AuthService.instance.authToken)",
"Content-Type": "application/json; charset=utf-8"
]
Alamofire.request(URL_USER_BY_USERNAME,
method: .get, parameters: nil, encoding: JSONEncoding.default,
headers:updated_HEADER).validate().responseJSON { (response) in }
}
Upvotes: 1