Skip to content

Commit 28b23f2

Browse files
committed
fix: token auth for websocket
1 parent 2a75c5a commit 28b23f2

3 files changed

Lines changed: 28 additions & 5 deletions

File tree

internal/auth/middleware.go

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,23 @@ func (s *Service) Middleware(next http.Handler) http.Handler {
3434
}
3535
}
3636

37+
// Try JWT token from query parameter (for WebSocket connections)
38+
if user == nil {
39+
tokenParam := r.URL.Query().Get("token")
40+
if tokenParam != "" {
41+
claims, err := s.ValidateJWT(tokenParam)
42+
if err != nil {
43+
sendError(w, http.StatusUnauthorized, err.Error())
44+
return
45+
}
46+
user = &AuthenticatedUser{
47+
Username: claims.Username,
48+
Role: claims.Role,
49+
AuthType: "jwt",
50+
}
51+
}
52+
}
53+
3754
// Try API key from X-API-Key header
3855
if user == nil {
3956
apiKey := r.Header.Get("X-API-Key")

web/src/pages/Messages.jsx

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ const WS_URL = import.meta.env.VITE_WS_URL ||
88
(window.location.protocol === 'https:' ? 'wss://' : 'ws://') + window.location.host
99

1010
function Messages() {
11-
const { isAdmin } = useAuth()
11+
const { isAdmin, token } = useAuth()
1212
const [messages, setMessages] = useState([])
1313
const [stats, setStats] = useState(null)
1414
const [loading, setLoading] = useState(true)
@@ -173,13 +173,16 @@ function Messages() {
173173
wsRef.current = null
174174
}
175175
}
176-
}, [liveUpdates, filters.stationId])
176+
}, [liveUpdates, filters.stationId, token])
177177

178178
const connectWebSocket = () => {
179179
try {
180180
// Build WebSocket URL with filters
181181
let wsUrl = `${WS_URL}/api/ws/messages`
182182
const params = new URLSearchParams()
183+
if (token) {
184+
params.append('token', token)
185+
}
183186
if (filters.stationId) {
184187
params.append('stationId', filters.stationId)
185188
}

web/src/pages/ScenarioRunner.jsx

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ const WS_URL = import.meta.env.VITE_WS_URL ||
77
(window.location.protocol === 'https:' ? 'wss://' : 'ws://') + window.location.host
88

99
function ScenarioRunner() {
10-
const { isAdmin } = useAuth()
10+
const { isAdmin, token } = useAuth()
1111
const [scenarios, setScenarios] = useState([])
1212
const [executions, setExecutions] = useState([])
1313
const [stations, setStations] = useState([])
@@ -85,7 +85,10 @@ function ScenarioRunner() {
8585
if (!activeExecution) return
8686

8787
const stationId = activeExecution.stationId
88-
const wsUrl = `${WS_URL}/api/ws/messages?stationId=${encodeURIComponent(stationId)}`
88+
const params = new URLSearchParams()
89+
if (token) params.append('token', token)
90+
params.append('stationId', stationId)
91+
const wsUrl = `${WS_URL}/api/ws/messages?${params.toString()}`
8992

9093
const connect = () => {
9194
wsRef.current = new WebSocket(wsUrl)
@@ -135,7 +138,7 @@ function ScenarioRunner() {
135138
wsRef.current.close()
136139
}
137140
}
138-
}, [activeExecution?.executionId, activeExecution?.stationId])
141+
}, [activeExecution?.executionId, activeExecution?.stationId, token])
139142

140143
// Poll for execution updates
141144
useEffect(() => {

0 commit comments

Comments
 (0)