0
votes

I am building a web app for dealing with 3D data, and want to render the 3D data belonging to each user. The 3D files (.obj, .mtl, png etc.) is stored in GCS, and the users should only be able to access their own 3D files.

I'm now trying to render the 3d files using three.js, but can't for the life of me find a good way to load the files using OBJLoader and MTLLoader. It works fine to load and render if I serve files as static content from my server, but I can't find a way of loading the non-public files stored in GCS.

I am using this code to load static files

const mtlFile = "test.mtl";
const objFIle = "test.obj";
var mtlLoader = new THREE.MTLLoader();
mtlLoader.load(mtlFile, function( materials ) {
    materials.preload();
    var objLoader = new THREE.OBJLoader();
    objLoader.setMaterials( materials );
    ObjLoader.load( objFile, function ( object ) {
        object.position.z = 40;
        scene.add( object );
    }, onProgress, onError );
});

The problem is that the my mtl file normally looks like this:

newmtl default
Ka 1.00 1.00 1.00
Kd 1.00 1.00 1.00
Ks 0.00 0.00 0.00
Ns 20.00
illum 2

newmtl test
Ka 1.00 1.00 1.00
Kd 1.00 1.00 1.00
Ks 0.00 0.00 0.00
Ns 20.00
illum 2
map_Ka test.png
map_Kd test.png

i.e. it points to a file called test.png. It's possible to set a base path, so if I could serve the file using an url http://example.com/test.png that would work here.

However, I want the files to only be accessible to the user that created them. And if I hosted the test.png in GCS I could get a signed link that looks like this:

https://storage.googleapis.com/test-bucket/test.png?GoogleAccessId=blajlakdsjflasjdflkj&Expires=14954&Signature=V92B0........

which I can't find a way to play nicely with the OBJ/MTL Loaders

So, any tips on how to solve this? Do I need to build some sort of file proxy that serves the files only connected to the user?

Btw. I'm hosting my own user database and authentication, so there's no connection to the user's google account.

1

1 Answers

0
votes

For ideal security, a proxy might suit your needs best. It wouldn't have to actually proxy all of the data. Maybe three.js handles redirects well? You could issue redirects to a signed URL.

However, it depends how you model the privacy of these objects. If you just give all of these objects lengthy random names that are effectively impossible to guess, you have mostly solved your security issue so long as no bad parties can learn the object name. That will quickly solve your problem without the need to build elaborate extra services.

Of course, security modeling is complicated. Do you care about the need to revoke access? Do you need to be able to limit how long a user can access an object? Should a user be able to share access to an object? I don't know the answers to these questions for your case. But long, unguessable names accessed anonymously via HTTPS may be sufficient for many of them.