快速注销后令牌不会变空

Posted

技术标签:

【中文标题】快速注销后令牌不会变空【英文标题】:Token not getting empty after logout swift 【发布时间】:2018-11-10 22:56:52 【问题描述】:

我有一个使用 API 进行身份验证的 swift 应用程序,一切正常,当用户注销时,登录令牌应该被清除,以便可以收集新用户的详细信息并将新令牌传递到标题中,但我注意到当我尝试登录另一个用户时,以前的用户令牌保留在标题中,从而阻止新用户登录。我在按下注销按钮时清除了登录值,但我不知道为什么令牌值保留在标题中。我的代码如下所示

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)")
        
    

令牌常数

let TOKEN_HEADER = [
    "Authorization": "Token \(AuthService.instance.authToken)",
    "Content-Type": "application/json; charset=utf-8"
]

用户服务

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 = ""

退出

@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)
    

可根据要求提供更多代码

【问题讨论】:

【参考方案1】:

问题是你认为每当你打电话给TOKEN_HEADER 你会得到最新的价值

 let TOKEN_HEADER = [
   "Authorization": "Token \(AuthService.instance.authToken)",
   "Content-Type": "application/json; charset=utf-8"
 ]

但这不会发生,因为无论令牌值是什么,变量都会从第一次初始化中获取它的值,因此您必须重构将标头发送到 Alamofire ,通过像这样再次硬编码字符串

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 


【讨论】:

那么如何更改变量以反映新变量 在方法中再次初始化它,请参阅答案,顺便说一句,对于每个 Alamofire 请求,它都应该是本地的,因为它应该被更新以反映最后一个值 不可能将两个令牌都传递到 alamofire。我不明白您的解决方案,请进一步解释 您将只传递一个更新后的标记查看编辑............我们的想法是我们在方法内创建另一个 var 以获取最新值作为外部值 TOKEN_HEADER 令牌更改时不会更改,因此请将其从应用程序中完全删除 非常感谢。这为我节省了很多时间。我很感激。我的应用程序有很多错误,我不知道你是否介意我发送其他问题的链接

以上是关于快速注销后令牌不会变空的主要内容,如果未能解决你的问题,请参考以下文章

Sanctum Laravel 8 用于 API 身份验证的问题(不会在注销时删除令牌)

注销方法不会从数据库中删除令牌

JWT 令牌在一定时间后不会过期

注销后删除访问令牌

角度注销后无法验证 CSRF 令牌的真实性

注销后的 CSRF 令牌生命周期