Skip to content

Commit f1363d9

Browse files
authored
Access token via auth header (#728)
1 parent e4b8510 commit f1363d9

2 files changed

Lines changed: 31 additions & 39 deletions

File tree

livekit-api/src/signal_client/mod.rs

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,8 @@ pub enum SignalError {
5555
WsError(#[from] WsError),
5656
#[error("failed to parse the url: {0}")]
5757
UrlParse(String),
58+
#[error("access token has invalid characters")]
59+
TokenFormat,
5860
#[error("client error: {0} - {1}")]
5961
Client(StatusCode, String),
6062
#[error("server error: {0} - {1}")]
@@ -245,12 +247,15 @@ impl SignalInner {
245247
proto::JoinResponse,
246248
mpsc::UnboundedReceiver<Box<proto::signal_response::Message>>,
247249
)> {
248-
let lk_url = get_livekit_url(url, token, &options)?;
250+
let lk_url = get_livekit_url(url, &options)?;
249251

250252
// Try to connect to the SignalClient
251-
let (stream, mut events) = match SignalStream::connect(lk_url.clone()).await {
253+
let (stream, mut events) = match SignalStream::connect(lk_url.clone(), token).await {
252254
Ok(stream) => stream,
253255
Err(err) => {
256+
if let SignalError::TokenFormat = err {
257+
return Err(err);
258+
}
254259
// Connection failed, try to retrieve more informations
255260
Self::validate(lk_url).await?;
256261
return Err(err);
@@ -314,10 +319,10 @@ impl SignalInner {
314319
let sid = &self.join_response.participant.as_ref().unwrap().sid;
315320
let token = self.token.lock().clone();
316321

317-
let mut lk_url = get_livekit_url(&self.url, &token, &self.options).unwrap();
322+
let mut lk_url = get_livekit_url(&self.url, &self.options).unwrap();
318323
lk_url.query_pairs_mut().append_pair("reconnect", "1").append_pair("sid", sid);
319324

320-
let (new_stream, mut events) = SignalStream::connect(lk_url).await?;
325+
let (new_stream, mut events) = SignalStream::connect(lk_url, &token).await?;
321326
let reconnect_response = get_reconnect_response(&mut events).await?;
322327
*stream = Some(new_stream);
323328

@@ -458,7 +463,7 @@ fn is_queuable(signal: &proto::signal_request::Message) -> bool {
458463
)
459464
}
460465

461-
fn get_livekit_url(url: &str, token: &str, options: &SignalOptions) -> SignalResult<url::Url> {
466+
fn get_livekit_url(url: &str, options: &SignalOptions) -> SignalResult<url::Url> {
462467
let mut lk_url = url::Url::parse(url).map_err(|err| SignalError::UrlParse(err.to_string()))?;
463468

464469
if !lk_url.has_host() {
@@ -482,7 +487,6 @@ fn get_livekit_url(url: &str, token: &str, options: &SignalOptions) -> SignalRes
482487
.query_pairs_mut()
483488
.append_pair("sdk", options.sdk_options.sdk.as_str())
484489
.append_pair("protocol", PROTOCOL_VERSION.to_string().as_str())
485-
.append_pair("access_token", token)
486490
.append_pair("auto_subscribe", if options.auto_subscribe { "1" } else { "0" })
487491
.append_pair("adaptive_stream", if options.adaptive_stream { "1" } else { "0" });
488492

@@ -533,14 +537,13 @@ mod tests {
533537

534538
#[test]
535539
fn livekit_url_test() {
536-
let it = "null_token";
537540
let io = SignalOptions::default();
538541

539-
assert!(get_livekit_url("localhost:7880", it, &io).is_err());
540-
assert_eq!(get_livekit_url("https://localhost:7880", it, &io).unwrap().scheme(), "wss");
541-
assert_eq!(get_livekit_url("http://localhost:7880", it, &io).unwrap().scheme(), "ws");
542-
assert_eq!(get_livekit_url("wss://localhost:7880", it, &io).unwrap().scheme(), "wss");
543-
assert_eq!(get_livekit_url("ws://localhost:7880", it, &io).unwrap().scheme(), "ws");
544-
assert!(get_livekit_url("ftp://localhost:7880", it, &io).is_err());
542+
assert!(get_livekit_url("localhost:7880", &io).is_err());
543+
assert_eq!(get_livekit_url("https://localhost:7880", &io).unwrap().scheme(), "wss");
544+
assert_eq!(get_livekit_url("http://localhost:7880", &io).unwrap().scheme(), "ws");
545+
assert_eq!(get_livekit_url("wss://localhost:7880", &io).unwrap().scheme(), "wss");
546+
assert_eq!(get_livekit_url("ws://localhost:7880", &io).unwrap().scheme(), "ws");
547+
assert!(get_livekit_url("ftp://localhost:7880", &io).is_err());
545548
}
546549
}

livekit-api/src/signal_client/signal_stream.rs

Lines changed: 15 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -28,14 +28,16 @@ use base64;
2828

2929
#[cfg(feature = "signal-client-tokio")]
3030
use tokio::{
31-
io::{AsyncRead, AsyncReadExt, AsyncWrite, AsyncWriteExt},
31+
io::{AsyncReadExt, AsyncWriteExt},
3232
net::TcpStream as TokioTcpStream,
3333
};
3434

3535
#[cfg(feature = "signal-client-tokio")]
3636
use tokio_tungstenite::{
3737
connect_async,
38+
tungstenite::client::IntoClientRequest,
3839
tungstenite::error::ProtocolError,
40+
tungstenite::http::{header::AUTHORIZATION, HeaderValue},
3941
tungstenite::{Error as WsError, Message},
4042
MaybeTlsStream, WebSocketStream,
4143
};
@@ -44,7 +46,9 @@ use tokio_tungstenite::{
4446
use async_tungstenite::{
4547
async_std::connect_async,
4648
async_std::ClientStream as MaybeTlsStream,
49+
tungstenite::client::IntoClientRequest,
4750
tungstenite::error::ProtocolError,
51+
tungstenite::http::{header::AUTHORIZATION, HeaderValue},
4852
tungstenite::{Error as WsError, Message},
4953
WebSocketStream,
5054
};
@@ -83,28 +87,13 @@ impl SignalStream {
8387
/// closed.
8488
pub async fn connect(
8589
url: url::Url,
90+
token: &str,
8691
) -> SignalResult<(Self, mpsc::UnboundedReceiver<Box<proto::signal_response::Message>>)> {
87-
{
88-
// Don't log sensitive info
89-
let mut url = url.clone();
90-
let filtered_pairs: Vec<_> = url
91-
.query_pairs()
92-
.filter(|(key, _)| key != "access_token")
93-
.map(|(k, v)| (k.into_owned(), v.into_owned()))
94-
.collect();
95-
96-
{
97-
let mut query_pairs = url.query_pairs_mut();
98-
query_pairs.clear();
99-
for (key, value) in filtered_pairs {
100-
query_pairs.append_pair(&key, &value);
101-
}
102-
103-
query_pairs.append_pair("access_token", "...");
104-
}
105-
106-
log::info!("connecting to {}", url);
107-
}
92+
log::info!("connecting to {}", url);
93+
let mut request = url.clone().into_client_request()?;
94+
let auth_header = HeaderValue::from_str(&format!("Bearer {token}"))
95+
.map_err(|_| SignalError::TokenFormat)?;
96+
request.headers_mut().insert(AUTHORIZATION, auth_header);
10897

10998
#[cfg(feature = "signal-client-tokio")]
11099
let ws_stream = {
@@ -300,24 +289,24 @@ impl SignalStream {
300289

301290
// Now perform WebSocket handshake over the established connection
302291
let (ws_stream, _) =
303-
tokio_tungstenite::client_async_with_config(url, stream, None).await?;
292+
tokio_tungstenite::client_async_with_config(request, stream, None).await?;
304293
ws_stream
305294
} else {
306295
// No proxy specified, connect directly
307-
let (ws_stream, _) = connect_async(url).await?;
296+
let (ws_stream, _) = connect_async(request).await?;
308297
ws_stream
309298
}
310299
} else {
311300
// Non-tokio build or no proxy - connect directly
312-
let (ws_stream, _) = connect_async(url).await?;
301+
let (ws_stream, _) = connect_async(request).await?;
313302
ws_stream
314303
};
315304

316305
ws_stream
317306
};
318307

319308
#[cfg(not(feature = "signal-client-tokio"))]
320-
let (ws_stream, _) = connect_async(url).await?;
309+
let (ws_stream, _) = connect_async(request).await?;
321310
let (ws_writer, ws_reader) = ws_stream.split();
322311

323312
let (emitter, events) = mpsc::unbounded_channel();

0 commit comments

Comments
 (0)