将 connectParams 与 JWT 一起使用时,Socket.connect() 不一致

Posted

技术标签:

【中文标题】将 connectParams 与 JWT 一起使用时,Socket.connect() 不一致【英文标题】:Socket.connect() is not consistent when using connectParams with JWT 【发布时间】:2018-02-06 16:09:57 【问题描述】:

我正在使用 https://github.com/auth0/socketio-jwt 将用户连接到我的 node.js/socket.io 服务器,并且我使用的是往返

我现在的问题是,每当用户登录 ios 部分时,socket.connect() 不一致,我的理论是即使在调用 socket.connect() 之前令牌还没有准备好。

正如许多人指出的那样,我正在为我的 Socket.io 类使用单例设计。

这是SocketManager.swift 部分的代码

import SocketIO

class SocketIOManager: NSObject 

    static let sharedInstance = SocketIOManager()
    var socket = SocketIOClient(socketURL: URL(string: mainURL)!, config: [.log(false), .compress, .connectParams(["token": getToken()])]) // getToken() I got it from other file which is Constant.Swift

    func establishConnection() 
        socket.connect()
    

    func closeConnection() 
        socket.disconnect()
           

我使用KeychainAccess 存储令牌,Constant.Swift 文件存储所有全局变量和函数,以便我可以在任何 Swift 文件上调用它。

Constant.Swift

import Foundation
import KeychainAccess

let keychain = Keychain(server: "www.example.com", protocolType: .https)

func getToken() -> String 
    if let token = keychain["token"] 
        return token
    
    return ""

LoginViewController.swift

@IBAction func facebookButtonClicked(_ sender: UIButton) 
       Alamofire.request("/login", method: .post, parameters: parameters, encoding: JSONEncoding.default)
            .responseJSON  response in
                if let value = response.result.value 
                    let json = JSON(value)

                    self.keychain["token"] = String(describing: json["token"])
                    SocketIOManager.sharedInstance.establishConnection() 
                    self.segueToAnotherVC() // Segue to another screen, to simplify things i put it in a function
                
        

所以从技术上讲,这个控制器中发生的事情是,当用户登录时,我会将令牌存储到 KeychainAccess 中(相当于 NSUserDefaults),然后只有我会建立一个套接字连接,因为套接字连接事先需要一个令牌.

每当用户登录时,我应该怎么做才能使连接始终保持一致?有什么方法可以用吗?

【问题讨论】:

如果您使用 NSUserDefaults 而不是 Keychain 访问,它是否可以正常工作?你已经试过了吗?另外,我建议您检查 getToken 方法是否返回正确的令牌。 另外,我认为您应该像这样使用钥匙串:https://***.com/questions/24324285/adding-items-to-and-querying-the-ios-keychain-with-swift 其余代码对我来说看起来不错,但对于 KeyChain,我不确定您是否正确使用它 @MohnishHirudkar 它确实返回了我已经检查过的正确令牌,因为当我在app.delegate 中建立连接时它可以工作,我相信创建令牌时间是这里的问题。 @sinusGob 您是否尝试将.log(false) 切换为.log(true) 以查看是否打印了任何其他调试信息?对我来说,这也可能是由于Alamofire异步回调位于非主线程中,而SocketIO认为需要在主线程中线。如果其中任何一个有帮助,LMK :) 您是否在 alamofire 正在连接的同一 URL 上打开此套接字连接? 【参考方案1】:

我建议你像这样使用钥匙串:

let keychain = KeychainSwift()
keychain.set("string", forKey: "key")
keychain.get("key")
keychain.delete("key")

钥匙串用法:

let saveBool: Bool = KeychainWrapper.setString("String", forKey: "key")  
let retrievedString: String? = KeychainWrapper.stringForKey("key")
let removeBool: Bool = KeychainWrapper.removeObjectForKey("key")

并确保在调用建立连接时设置了您的令牌,如果没有,请不要尝试连接。

参考文献:

https://github.com/socketio/socket.io-client-swift/issues/788

https://github.com/marketplacer/keychain-swift

https://github.com/jrendel/SwiftKeychainWrapper

更多信息:

JSON Web Token 是一个基于 JSON 的开放标准,用于创建声明一些声明的访问令牌。

【讨论】:

以上是关于将 connectParams 与 JWT 一起使用时,Socket.connect() 不一致的主要内容,如果未能解决你的问题,请参考以下文章

将 JWT 与 nodejs 和 express 一起使用

如何将 JWT 与 grpc 一起使用?

如何将flask_jwt_extended 与蓝图一起使用?

将 JWT 与 Ktor 一起使用并在声明中包含用户信息

SailsJS - 将sails.io.js 与JWT 一起使用

markdown 将JWT与Kong一起使用的简短示例