Skip to content

Commit ac5e5ed

Browse files
authored
Generate Websocket token from auth in Unity WebGL build (#2988)
# Description of Changes This is a fix for community bug which auth token is not used to create Websocket connection in Unity WebGL build. The issue here: #352 # API and ABI breaking changes None # Expected complexity level and risk 1 # Testing - [ ] Using OAuth2.0 tokens, you should get the same `Identity` even when the token is refreshed in the WebGL build
1 parent 3908157 commit ac5e5ed

File tree

2 files changed

+36
-5
lines changed

2 files changed

+36
-5
lines changed

src/Plugins/WebSocket.jslib

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,33 @@ mergeInto(LibraryManager.library, {
1818
manager.callbacks.error = errorCallback;
1919
},
2020

21-
WebSocket_Connect: function(uriPtr, protocolPtr, authTokenPtr) {
21+
WebSocket_Connect: async function(baseUriPtr, uriPtr, protocolPtr, authTokenPtr, callbackPtr) {
2222
try {
2323
var manager = this._webSocketManager;
24+
var host = UTF8ToString(baseUriPtr);
2425
var uri = UTF8ToString(uriPtr);
2526
var protocol = UTF8ToString(protocolPtr);
2627
var authToken = UTF8ToString(authTokenPtr);
28+
if (authToken)
29+
{
30+
var tokenUrl = new URL('v1/identity/websocket-token', host);
31+
tokenUrl.protocol = host.startsWith("wss://") ? 'https:' : 'http:';
32+
var headers = new Headers();
33+
headers.set('Authorization', `Bearer ${authToken}`);
34+
35+
var response = await fetch(tokenUrl, {
36+
method: 'POST',
37+
headers: headers
38+
});
39+
if (response.ok) {
40+
const { token } = await response.json();
41+
if (token) {
42+
uri += `&token=${token}`;
43+
}
44+
} else {
45+
throw new Error(`Failed to verify token: ${response.statusText}`);
46+
}
47+
}
2748

2849
var socket = new window.WebSocket(uri, protocol);
2950
socket.binaryType = "arraybuffer";
@@ -63,10 +84,10 @@ mergeInto(LibraryManager.library, {
6384
}
6485
};
6586

66-
return socketId;
87+
dynCall('vi', callbackPtr, [socketId]);
6788
} catch (e) {
6889
console.error("WebSocket connection error:", e);
69-
return -1;
90+
dynCall('vi', callbackPtr, [-1]);
7091
}
7192
},
7293

src/WebSocket.cs

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ IntPtr errorCallback
7575
);
7676

7777
[DllImport("__Internal")]
78-
private static extern int WebSocket_Connect(string uri, string protocol, string authToken);
78+
private static extern int WebSocket_Connect(string host, string uri, string protocol, string authToken, IntPtr callbackPtr);
7979

8080
[DllImport("__Internal")]
8181
private static extern int WebSocket_Send(int socketId, byte[] data, int length);
@@ -118,8 +118,15 @@ private static void WebGLOnError(int socketId)
118118
Instance?.HandleWebGLError(socketId);
119119
}
120120

121+
[AOT.MonoPInvokeCallback(typeof(Action<int>))]
122+
private static void OnSocketIdReceived(int socketId)
123+
{
124+
Instance?._socketId.TrySetResult(socketId);
125+
}
126+
121127
private static WebSocket Instance;
122128
private int _webglSocketId = -1;
129+
private TaskCompletionSource<int> _socketId;
123130

124131
private void InitializeWebGL()
125132
{
@@ -145,7 +152,10 @@ public async Task Connect(string? auth, string host, string nameOrAddress, Conne
145152
var uri = $"{host}/v1/database/{nameOrAddress}/subscribe?connection_id={connectionId}&compression={compression}";
146153
if (light) uri += "&light=true";
147154

148-
_webglSocketId = WebSocket_Connect(uri, _options.Protocol, auth);
155+
_socketId = new TaskCompletionSource<int>();
156+
var callbackPtr = Marshal.GetFunctionPointerForDelegate((Action<int>)OnSocketIdReceived);
157+
WebSocket_Connect(host, uri, _options.Protocol, auth, callbackPtr);
158+
_webglSocketId = await _socketId.Task;
149159
if (_webglSocketId == -1)
150160
{
151161
dispatchQueue.Enqueue(() => OnConnectError?.Invoke(

0 commit comments

Comments
 (0)