Open Haoran-Qi opened 9 months ago
Did you make a copy of superset-websocket/config.example.json
as superset-websocket/config.json
and change the jwtSecret
value? You can use https://jwt.io/ to generate a valid token. I don't think it matters what the payload is, just have to be a valid JWT.
Yeah, I did make the superset-websocket/config.json file with 32 bytes secret key, same key as the GLOBAL_ASYNC_QUERIES_JWT_SECRET I set up in docker/pythonpath_dev/superset_config.py.
In superset app container https://github.com/apache/superset/blob/9900f566700e6d0a2c376aa4260a0a3f4db27404/superset-frontend/src/middleware/asyncEvent.ts#L196
I don't think it provids the JWT in the header, that's why websocket container is giving a JWT not present error
If the token is invalid, it should throw an error with the jwt verification failure in the following line.
I am facing the same issue with Kubernetes deployment. JWT
Is anyone still facing this? It seems to have gone silent, so may eventually be closed as stale. In the meantime, the websocket connection is being addressed in a forthcoming SIP by @villebro and subject to architecture redesign.
For good measure, I'll also ping @dosu-bot in case it's helpful here.
Hey @rusackas! I'm here to help you with any bugs, questions, or contributions. I'm Dosu, a bot designed to assist you while you wait for a human maintainer. Let me know how I can help!
To address the "JWT not present" error in the WebSocket connection for Superset's async query feature, ensure the following configurations and steps are correctly implemented:
Configuration Settings:
GLOBAL_ASYNC_QUERIES_JWT_SECRET
and GLOBAL_ASYNC_QUERIES_JWT_COOKIE_NAME
are set correctly in your superset_config.py
and match the values in superset-websocket/config.json
.Environment Variables:
JWT_SECRET
and JWT_COOKIE_NAME
environment variables to match the values used in your configuration.WebSocket Configuration:
superset-websocket/config.json
file is correctly configured with the jwtSecret
and jwtCookieName
values. Here is an example configuration:
{
"port": 8080,
"logLevel": "info",
"logToFile": false,
"logFilename": "app.log",
"statsd": {
"host": "127.0.0.1",
"port": 8125,
"globalTags": []
},
"redis": {
"port": 6379,
"host": "127.0.0.1",
"password": "",
"db": 0,
"ssl": false
},
"redisStreamPrefix": "async-events-",
"jwtAlgorithms": ["HS256"],
"jwtSecret": "YOUR_32_BYTE_SECRET_KEY",
"jwtCookieName": "async-token"
}
Session and Cookie Handling:
async_query_manager.py
file should correctly create the channel_id
and set the JWT cookie. Ensure the validate_session
method is properly setting the cookie:
def register_request_handlers(self, app: Flask) -> None:
@app.after_request
def validate_session(response: Response) -> Response:
user_id = get_user_id()
reset_token = (
not request.cookies.get(self._jwt_cookie_name)
or "async_channel_id" not in session
or "async_user_id" not in session
or user_id != session["async_user_id"]
)
if reset_token:
async_channel_id = str(uuid.uuid4())
session["async_channel_id"] = async_channel_id
session["async_user_id"] = user_id
sub = str(user_id) if user_id else None
token = jwt.encode(
{"channel": async_channel_id, "sub": sub},
self._jwt_secret,
algorithm="HS256",
)
response.set_cookie(
self._jwt_cookie_name,
value=token,
httponly=True,
secure=self._jwt_cookie_secure,
domain=self._jwt_cookie_domain,
samesite=self._jwt_cookie_samesite,
)
return response
WebSocket Connection:
const jwt = require('jsonwebtoken');
const WebSocket = require('ws');
const token = jwt.sign(
{ "channel": "1234122341234" },
"YOUR_32_BYTE_SECRET_KEY"
);
const socket = new WebSocket('ws://127.0.0.1:8080/', {
headers: {
cookie: "async-token=" + token
}
});
socket.onopen = function (event) {
console.log('WebSocket connection established.');
};
Check for Updates:
By ensuring these configurations and steps are correctly implemented, the "JWT not present" error should be resolved [1][2][3].
To continue talking to Dosu, mention @dosu.
I'm still having the same problem.
Bug description
Hi
I find a bug in the Async Query Websocket code while I'm trying to enable the Async query "ws" mode I followed the instructions and docs to set up all the config values https://github.com/apache/superset/blob/master/CONTRIBUTING.md#async-chart-queries https://github.com/apache/superset/issues/9190
In the websocket code, it is looking for the channel_id from cookie encrypted by JWT https://github.com/apache/superset/blob/9900f566700e6d0a2c376aa4260a0a3f4db27404/superset-websocket/src/index.ts#L278
However in the sueprset_app's ws connection, we are not provbiding proper JWT token to establish WS connection https://github.com/apache/superset/blob/9900f566700e6d0a2c376aa4260a0a3f4db27404/superset-frontend/src/middleware/asyncEvent.ts#L196
Which lead to a JWT not present error.
I try to connects to the Websocket conatainer locally with following code, and it works
I notice the we create the channel_id and set the cookie in async_mananger, but I don't think it reflects on websocket container https://github.com/apache/superset/blob/9900f566700e6d0a2c376aa4260a0a3f4db27404/superset/async_events/async_query_manager.py#L157
How to reproduce the bug
my config GLOBAL_ASYNC_QUERIES_JWT_SECRET = "***" GLOBAL_ASYNC_QUERIES_TRANSPORT = "ws" GLOBAL_ASYNC_QUERIES_JWT_COOKIE_SECURE = True GLOBAL_ASYNC_QUERIES_REDIS_CONFIG = { "port": REDIS_PORT, "host": REDIS_HOST, "password": "", "db": 0, "ssl": False, }
Screenshots/recordings
No response
Superset version
master / latest-dev
Python version
3.9
Node version
16
Browser
Chrome
Additional context
No response
Checklist