英文:
WebSocket JWT Token connection authorization
问题
我正在尝试与一个URL(Python客户端)建立WebSocket连接,需要传递一个JWT令牌,并且服务器(使用GO实现)监听此请求并应通过解析令牌进行身份验证。
我尝试使用以下代码部分进行请求 -
def test_auth_token(token):
conn = create_connection("ws://<IP>:port"+ '/' + container.uuid + '?token=' + token)
result = conn.recv()
assert result is not None
这个请求会触发运行以下代码的服务器来验证此请求:
func ParseFromRequest(req *http.Request, keyFunc Keyfunc) (token *Token, err error) {
// 查找Authorization头部
if ah := req.Header.Get("Authorization"); ah != "" {
// 应该是一个Bearer令牌
if len(ah) > 6 && strings.ToUpper(ah[0:6]) == "BEARER" {
return Parse(ah[7:], keyFunc)
}
}
// 查找"access_token"参数
req.ParseMultipartForm(10e6)
if tokStr := req.Form.Get("access_token"); tokStr != "" {
return Parse(tokStr, keyFunc)
}
return nil, ErrNoTokenInRequest
}
每次,尽管我将令牌作为查询参数传递,但我仍然得到"ErrNoTokenInRequest"的输出。服务器端的令牌验证是由此外部库完成的,该库包含上述GO例程 - https://github.com/dgrijalva/jwt-go/blob/master/jwt.go
我不确定服务器找不到我在客户端发送的令牌的可能原因是什么?它应该作为有效载荷、标头或其他内容发送吗?有人能指点一下如何使这个模块工作吗?
使用"access_token"作为查询参数,我得到以下异常 -
self = <websocket._core.WebSocket object at 0x10a15a6d0>
host = 'x.x.x.x.', port = 9345
resource = '/v1/stats/fff51e85-f2bb-4ace-8dcc-fde590932cca?access_token=eyJhbGciOiJSUzI1NiJ9.eyJleHAiOjE0MjIxMzEyMzUsInN1YiI6ImNh...vxvBmtZRrUTY5AcvrjbojXqLxFHL_CMsmTZfTXhOiy-7W2V95bqts2Wy4R8oQvsfDylYJWCBTzZNKHvPVFpcl0jQKLm1ms-LOJg1w-k23VfojZucPGtY5A';
options = {}
headers = ['GET /v1/stats/fff51e85-f2bb-4ace-8dcc-fde590932cca?access_token=eyJhbGciOiJSUzI1NiJ9.eyJleHAiOjE0MjIxMzEyMzUsInN1YiI... 'Host: x.x.x.x.:9345', 'Origin: http://x.x.x.x.:9345', 'Sec-WebSocket-Key: BN1n2BcCT/CUGh9MHeyL5g==', ...]
key = 'BN1n2BcCT/CUGh9MHeyL5g=='
header_str = 'GET /v1/stats/fff51e85-f2bb-4ace-8dcc-fde590932cca?access_token=eyJhbGciOiJSUzI1NiJ9.eyJleHAiOjE0MjIxMzEyMzUsInN1YiI6...3:9345
Origin: http://192.168.59.103:9345
Sec-WebSocket-Key: BN1n2BcCT/CUGh9MHeyL5g==
Sec-WebSocket-Version: 13
英文:
I am trying to make a websocket connection to a URL(python client) which needs to have a jwt token passed in and the server(implemented in GO) listens to this request on and is supposed to authenticate by parsing the token.
I try to use this part of the code to make the request -
def test_auth_token(token)
conn = create_connection("ws://<IP>:port"+ '/'+ container.uuid + '?token='+token)
result = conn.recv()
assert result is not None
This request hits the server which runs this code to validate this request
func ParseFromRequest(req *http.Request, keyFunc Keyfunc) (token *Token, err error) {
// Look for an Authorization header
if ah := req.Header.Get("Authorization"); ah != "" {
// Should be a bearer token
if len(ah) > 6 && strings.ToUpper(ah[0:6]) == "BEARER" {
return Parse(ah[7:], keyFunc)
}
}
// Look for "access_token" parameter
req.ParseMultipartForm(10e6)
if tokStr := req.Form.Get("access_token"); tokStr != "" {
return Parse(tokStr, keyFunc)
}
return nil, ErrNoTokenInRequest
}
Every time, I am getting the "ErrNoTokenInRequest" output despite I am passing the token as a query parameter. The server side token validation is being done by this external library which contains the above GO Routine - https://github.com/dgrijalva/jwt-go/blob/master/jwt.go
I am not sure, what could be the possible reasons that server doesn't find the token sent in my client? Is it supposed to be sent as payload or headers or something else? Could someone point to get this module working?
With "access_token" as query parameter i get this exception -
self = <websocket._core.WebSocket object at 0x10a15a6d0>
host = 'x.x.x.x.', port = 9345
resource = '/v1/stats/fff51e85-f2bb-4ace-8dcc-fde590932cca?access_token=eyJhbGciOiJSUzI1NiJ9.eyJleHAiOjE0MjIxMzEyMzUsInN1YiI6ImNh...vxvBmtZRrUTY5AcvrjbojXqLxFHL_CMsmTZfTXhOiy-7W2V95bqts2Wy4R8oQvsfDylYJWCBTzZNKHvPVFpcl0jQKLm1ms-LOJg1w-k23VfojZucPGtY5A'
options = {}
headers = ['GET /v1/stats/fff51e85-f2bb-4ace-8dcc-fde590932cca?access_token=eyJhbGciOiJSUzI1NiJ9.eyJleHAiOjE0MjIxMzEyMzUsInN1YiI... 'Host: x.x.x.x.:9345', 'Origin: http://x.x.x.x.:9345', 'Sec-WebSocket-Key: BN1n2BcCT/CUGh9MHeyL5g==', ...]
key = 'BN1n2BcCT/CUGh9MHeyL5g=='
header_str = 'GET /v1/stats/fff51e85-f2bb-4ace-8dcc-fde590932cca?access_token=eyJhbGciOiJSUzI1NiJ9.eyJleHAiOjE0MjIxMzEyMzUsInN1YiI6...3:9345
Origin: http://192.168.59.103:9345
Sec-WebSocket-Key: BN1n2BcCT/CUGh9MHeyL5g==
Sec-WebSocket-Version: 13
答案1
得分: 2
简单来说,服务器不希望令牌作为查询参数传递,而是希望将其包含在请求的头部中。
使用来自https://github.com/liris/websocket-client的websocket库的示例:
def test_auth_token(token):
header = "Authorization: BEARER " + str(token)
conn = create_connection("ws://<IP>:port" + '/' + container.uuid, header)
result = conn.recv()
assert result is not None
英文:
Quite simply the serve does not expect the token to be handed over as a query parameter but instead expects it to be included in the headers of the request.
Example using the websocket library from https://github.com/liris/websocket-client
def test_auth_token(token)
header="Authorization: BEARER " + str(token)
conn = create_connection("ws://<IP>:port"+ '/'+ container.uuid", header)
result = conn.recv()
assert result is not None
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论