Skip to content

Commit 636750b

Browse files
authored
Switch to using header based auth bearer token (#770)
* Switch to using header based auth bearer token * spotless * Fix tests
1 parent 0b1d083 commit 636750b

File tree

5 files changed

+40
-8
lines changed

5 files changed

+40
-8
lines changed

.changeset/nervous-rings-suffer.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"client-sdk-android": patch
3+
---
4+
5+
Switch to using header based auth bearer token

livekit-android-sdk/src/main/java/io/livekit/android/room/SignalClient.kt

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,7 @@ constructor(
163163
// Clean up any pre-existing connection.
164164
close(reason = "Starting new connection", shouldClearQueuedRequests = false)
165165

166-
val wsUrlString = "${url.toWebsocketUrl()}/rtc" + createConnectionParams(token, getClientInfo(), options, roomOptions)
166+
val wsUrlString = "${url.toWebsocketUrl()}/rtc" + createConnectionParams(getClientInfo(), options, roomOptions)
167167
isReconnecting = options.reconnect
168168

169169
LKLog.i { "connecting to $wsUrlString" }
@@ -175,6 +175,7 @@ constructor(
175175

176176
val request = Request.Builder()
177177
.url(wsUrlString)
178+
.addHeader("Authorization", "Bearer $token")
178179
.build()
179180

180181
return suspendCancellableCoroutine {
@@ -185,13 +186,11 @@ constructor(
185186
}
186187

187188
private fun createConnectionParams(
188-
token: String,
189189
clientInfo: LivekitModels.ClientInfo,
190190
options: ConnectOptions,
191191
roomOptions: RoomOptions,
192192
): String {
193193
val queryParams = mutableListOf<Pair<String, String>>()
194-
queryParams.add(CONNECT_QUERY_TOKEN to token)
195194
queryParams.add(CONNECT_QUERY_PROTOCOL to options.protocolVersion.value.toString())
196195

197196
if (options.reconnect) {
@@ -308,9 +307,18 @@ constructor(
308307
}
309308
var reason: String? = null
310309
try {
310+
val lastToken = webSocket.request().header("Authorization")
311311
lastUrl?.let {
312312
val validationUrl = it.toHttpUrl().replaceFirst("/rtc?", "/rtc/validate?")
313-
val request = Request.Builder().url(validationUrl).build()
313+
val request = Request.Builder()
314+
.url(validationUrl)
315+
.apply {
316+
if (lastToken != null) {
317+
addHeader("Authorization", lastToken)
318+
}
319+
}
320+
.build()
321+
314322
val resp = okHttpClient.newCall(request).execute()
315323
val body = resp.body
316324
if (!resp.isSuccessful) {

livekit-android-test/src/main/java/io/livekit/android/test/MockE2ETest.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ abstract class MockE2ETest : BaseTest() {
7878
val job = coroutineRule.scope.launch {
7979
room.connect(
8080
url = TestData.EXAMPLE_URL,
81-
token = "",
81+
token = "token",
8282
)
8383
}
8484
wsFactory.listener.onOpen(wsFactory.ws, createOpenResponse(wsFactory.request))

livekit-android-test/src/test/java/io/livekit/android/room/RTCEngineMockE2ETest.kt

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -127,12 +127,16 @@ class RTCEngineMockE2ETest : MockE2ETest() {
127127
fun refreshToken() = runTest {
128128
connect()
129129

130-
val oldToken = wsFactory.request.url.queryParameter(SignalClient.CONNECT_QUERY_TOKEN)
130+
val oldToken = wsFactory.request.header("Authorization")
131+
?.split(" ")
132+
?.get(1)
131133
wsFactory.listener.onMessage(wsFactory.ws, TestData.REFRESH_TOKEN.toOkioByteString())
132134
wsFactory.listener.onFailure(wsFactory.ws, Exception(), null)
133135

134136
testScheduler.advanceUntilIdle()
135-
val newToken = wsFactory.request.url.queryParameter(SignalClient.CONNECT_QUERY_TOKEN)
137+
val newToken = wsFactory.request.header("Authorization")
138+
?.split(" ")
139+
?.get(1)
136140
Assert.assertNotEquals(oldToken, newToken)
137141
assertEquals(TestData.REFRESH_TOKEN.refreshToken, newToken)
138142
}

livekit-android-test/src/test/java/io/livekit/android/room/SignalClientTest.kt

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2023-2024 LiveKit, Inc.
2+
* Copyright 2023-2025 LiveKit, Inc.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -94,6 +94,21 @@ class SignalClientTest : BaseTest() {
9494
client.onMessage(wsFactory.ws, JOIN.toOkioByteString())
9595
}
9696

97+
@Test
98+
fun usesAuthToken() = runTest {
99+
val token = "this-is-an-auth-token"
100+
val job = async {
101+
client.join(EXAMPLE_URL, token)
102+
}
103+
104+
connectWebsocketAndJoin()
105+
job.await()
106+
val ws = wsFactory.ws
107+
108+
assertEquals("Bearer $token", ws.request().header("Authorization"))
109+
assertFalse(ws.request().url.query?.contains(token) ?: true)
110+
}
111+
97112
@Test
98113
fun joinAndResponse() = runTest {
99114
val job = async {

0 commit comments

Comments
 (0)