Skip to content

Generate Websocket token from auth in Unity WebGL build #2988

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Jul 28, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 24 additions & 3 deletions sdks/csharp/src/Plugins/WebSocket.jslib
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,33 @@ mergeInto(LibraryManager.library, {
manager.callbacks.error = errorCallback;
},

WebSocket_Connect: function(uriPtr, protocolPtr, authTokenPtr) {
WebSocket_Connect: async function(baseUriPtr, uriPtr, protocolPtr, authTokenPtr, callbackPtr) {
try {
var manager = this._webSocketManager;
var host = UTF8ToString(baseUriPtr);
var uri = UTF8ToString(uriPtr);
var protocol = UTF8ToString(protocolPtr);
var authToken = UTF8ToString(authTokenPtr);
if (authToken)
{
var tokenUrl = new URL('v1/identity/websocket-token', host);
tokenUrl.protocol = host.startsWith("wss://") ? 'https:' : 'http:';
var headers = new Headers();
headers.set('Authorization', `Bearer ${authToken}`);

var response = await fetch(tokenUrl, {
method: 'POST',
headers: headers
});
if (response.ok) {
const { token } = await response.json();
if (token) {
uri += `&token=${token}`;
}
} else {
throw new Error(`Failed to verify token: ${response.statusText}`);
}
}

var socket = new window.WebSocket(uri, protocol);
socket.binaryType = "arraybuffer";
Expand Down Expand Up @@ -63,10 +84,10 @@ mergeInto(LibraryManager.library, {
}
};

return socketId;
dynCall('vi', callbackPtr, [socketId]);
} catch (e) {
console.error("WebSocket connection error:", e);
return -1;
dynCall('vi', callbackPtr, [-1]);
}
},

Expand Down
14 changes: 12 additions & 2 deletions sdks/csharp/src/WebSocket.cs
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ IntPtr errorCallback
);

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

[DllImport("__Internal")]
private static extern int WebSocket_Send(int socketId, byte[] data, int length);
Expand Down Expand Up @@ -118,8 +118,15 @@ private static void WebGLOnError(int socketId)
Instance?.HandleWebGLError(socketId);
}

[AOT.MonoPInvokeCallback(typeof(Action<int>))]
private static void OnSocketIdReceived(int socketId)
{
Instance?._socketId.TrySetResult(socketId);
}

private static WebSocket Instance;
private int _webglSocketId = -1;
private TaskCompletionSource<int> _socketId;

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

_webglSocketId = WebSocket_Connect(uri, _options.Protocol, auth);
_socketId = new TaskCompletionSource<int>();
var callbackPtr = Marshal.GetFunctionPointerForDelegate((Action<int>)OnSocketIdReceived);
WebSocket_Connect(host, uri, _options.Protocol, auth, callbackPtr);
_webglSocketId = await _socketId.Task;
if (_webglSocketId == -1)
{
dispatchQueue.Enqueue(() => OnConnectError?.Invoke(
Expand Down
Loading