Google Cloud Storage en private files per user

Pagina: 1
Acties:

Acties:
  • 0 Henk 'm!

  • Saven
  • Registratie: December 2006
  • Laatst online: 02-10 16:35

Saven

Administrator

Topicstarter
Ik ben bezig met een PHP/MySQL projectje waar users berichten en attachments kunnen ontvangen. Om die bestanden op te slaan ben ik van plan om gebruik te maken van Google Cloud Storage. Berichten kunnen dan bijv naast een "lijst met attachmentnamen" ook inline afbeeldingen bevatten, waarvan de content dus meteen zichtbaar is bij het zien van dit bericht.

In een attachments bucket zullen deze files worden opgeslagen, bijvoorbeeld met als pad /attachments/<user_id>/<message_id>/<db_file_id>/filename.ext. Geavanceerd ACL is ingeschakeld.

So far so good volgens mij. Het uploaden is niet zo spannend, de bestanden worden vervolgens als niet openbaar ingesteld.

Nu twijfel ik alleen over de beste aanpak om de bestanden weer op te halen. Ik heb volgens mij deze mogelijkheden:

1. Publieke bestanden gebruiken met random filenames, zodat die URL meteen bij elke file in de database wordt opgeslagen, waardoor er geen enkele latency/overhead is.

2. In feite een PHP proxy gebruiken waarbij een view.php?id=XX de niet-publieke content vanuit GCS uitleest, en vervolgens output naar de user. In view.php kan ik controleren of de user de juiste rechten heeft en de user heeft geen idee dat het bestand in GCS staat.

3a. View.php?id=XX haalt voor elke attachment een signed URL bij GCS op, en redirect de user naar deze URL. De user heeft dan de volledige URL, iedereen met deze URL kan het bestand opvragen.

3b. Ook een signed URL, maar dan met een limit van bijv. 15 minuten. Dan is de URL 'publiekelijk' max. 15 min te benaderen.

Optie 1 lijkt me eigenlijk wel meteen af te vallen, immers een hoog potentieel veiligheids-/privacyrisico.

Optie 2 klinkt op het eerste gezicht wel een goede optie maar daar lijkt het me dat je met dubbele bandwith zit en meer latency overhead hebt? Immers moet het bestand eerst van GCS worden gedownload, en dan geserveerd worden aan de user.

Optie 3 geeft minder mooie URL's - signed URL's zijn nu eenmaal vrij lang en 'lelijk'. Daarbij zit je ook nog met (enige?) overhead. Want bij inline images moet direct een signed URL worden opgehaald. Wanneer je dit niet met AJAX zou doen, en er 10 afbeeldingen in één bericht staan, heb je 10 x ~100ms(?) latency voordat het script verder kan worden uitgevoerd?

De lijst met (niet inline) attachments kunnen nog steeds doorlinken naar View.php?id=xx. Daardoor heb je daar slechts 1 x ~100ms latency.

Bij 3a zou dit probleem maar één keer optreden omdat de signed URL onbeperkt houdbaar is, daar da's bijna hetzelfde als optie 1. Bij 3b zou je bij elke page refresh bij wijze van spreken hetzelfde proces moeten doorlopen.

Wat zouden jullie doen, zijn er andere best practices hiervoor? Hoop dat ik het een beetje duidelijk heb omschreven :)

Acties:
  • 0 Henk 'm!

  • Kalentum
  • Registratie: Juni 2004
  • Laatst online: 20:25
Interessant. Wij gebruiken ook GCS voor user uploaded afbeeldingen maar die data is publiek (wel met een randomfile name overigens)

Ik zou voor optie 2 gaan. Volgens mij kun je in PHP met fpasshru() functie redelijk efficient data naar de browser sturen. Maar ik ken je use case niet: over hoeveel dataverkeer hebben we het? En hoeveel berichten? En hoe groot worden die bestanden? Het kan zelfs zo zijn dat lokaal cachen zin heeft als bv de wat oudere berichten bijna nooit opgevraagd worden.

Ik denk dat netwerklatency niet zo'n issue is voor downloads.

Acties:
  • 0 Henk 'm!

  • Postman
  • Registratie: Februari 2000
  • Laatst online: 26-09 12:50
Optie 1 en 3 zijn qua beveiliging en privacy eigenlijk hetzelfde.
Mocht dit een issue zijn dan blijft alleen optie 2 over.

Een compleet andere mogelijkheid is het gebruik van encryptie. Je zult dan het bestand aan de gebruikerkant moeten decrypten (via JavaScript). Dit geeft geen dubbel dataverkeer, maar kan weer tot problemen leiden met beveiliging. Eventueel in combinatie met een time-out functie zoals in 3b, hoewel je dan inderdaad weer problemen kunt krijgen met caching en page reloading.

Acties:
  • 0 Henk 'm!

  • Saven
  • Registratie: December 2006
  • Laatst online: 02-10 16:35

Saven

Administrator

Topicstarter
Kalentum schreef op zondag 19 april 2020 @ 16:18:
Interessant. Wij gebruiken ook GCS voor user uploaded afbeeldingen maar die data is publiek (wel met een randomfile name overigens)

Ik zou voor optie 2 gaan. Volgens mij kun je in PHP met fpasshru() functie redelijk efficient data naar de browser sturen. Maar ik ken je use case niet: over hoeveel dataverkeer hebben we het? En hoeveel berichten? En hoe groot worden die bestanden? Het kan zelfs zo zijn dat lokaal cachen zin heeft als bv de wat oudere berichten bijna nooit opgevraagd worden.

Ik denk dat netwerklatency niet zo'n issue is voor downloads.
Hmm passthru dat niet gewoon een veredelde reafile/file_get_contents? Potentieel om een hoop data, dus ik wil t zo goed mogelijk uitdenken :)
Postman schreef op zondag 19 april 2020 @ 21:45:
Optie 1 en 3 zijn qua beveiliging en privacy eigenlijk hetzelfde.
Mocht dit een issue zijn dan blijft alleen optie 2 over.

Een compleet andere mogelijkheid is het gebruik van encryptie. Je zult dan het bestand aan de gebruikerkant moeten decrypten (via JavaScript). Dit geeft geen dubbel dataverkeer, maar kan weer tot problemen leiden met beveiliging. Eventueel in combinatie met een time-out functie zoals in 3b, hoewel je dan inderdaad weer problemen kunt krijgen met caching en page reloading.
JS encryptie gaat idd wel erg ver :P Zo doen grote namen zoals Zendesk en Slack het ook niet volgens mij. Enig idee hoe zij dit aanpakken?

Acties:
  • 0 Henk 'm!

  • Kalentum
  • Registratie: Juni 2004
  • Laatst online: 20:25
Saven schreef op maandag 20 april 2020 @ 12:09:
[...]

Hmm passthru dat niet gewoon een veredelde reafile/file_get_contents? Potentieel om een hoop data, dus ik wil t zo goed mogelijk uitdenken :)
Ja, het moet inderdaad anders. Je moet alleen zorgen dat die file niet in het geheel in het werkgeheugen komt te staan