views:

95

answers:

3

I'm making a gallery website. Photos and albums should be hidden from the public by default, but the owner can share a public URL if he wants. I also want to use short URLs for this.

I'm trying to figure out the best way to do this. At first I thought I could have a MySQL table with the short URL code (something like Zneg8rjK), and the full URL (/album/5/). When the user visits this link (mysite.com/Zneg8rjK) it would set a session variable which is just a hash of /album/5 plus a salt, and then it redirects them to the full URL. Then on that page I can just rehash the current page and check if it's in their session or not. No problem... but what happens when they click on a photo in that album? It breaks down.

So, the next solution I thought of was that I should store a secret key with each album and each photo, and then have a public address like /album/5/secretkey. The short URL could just point to this instead. But then how do I give the user to permission to view all the photos in the album? Should I just link each photo to point to the secret version of the photo URL instead, but only if they accessed the album via the secret album URL? My concern is that I want to keep the secret keys/URLs out of the address bar as much as possible so that users don't accidentally share it with people they shouldn't... but it's not a huge concern if there aren't any better solutions.

Thoughts?


Wait a sec, do I even need to hash the URL? There's no way for clients to modify session variables is there?

+2  A: 

I guess it depends a bit on how you check permissions - I'd suggest having a key for a whole album, and a key for individual photo's.

The redirect thing in the first part of your post actually doesn't sound that bad to me, only you'd have to check the supplied key in the session against 2 valid options - one for the individual photo, and one for the album that contains that photo. If either one validates, show the photo (instead of 'break down').

Hope this helps!

ylebre
Yeah... well, I'd have to rebuild the album URL from the photo page instead of using $_SERVER['REQUEST_URI'] or something of the sort to do the extra check, but I guess that's not really a problem. I guess that isn't so bad. Thanks
Mark
+1  A: 

You would probably want to do the two keys like the above person said. You might not want to restrict access going through one URL like mysite.com/hashhere instead you should have the short URL be able to include the hash, so if they have the right hash no matter what link they go to, they can view it.

To make it even more secure, give the owner of the gallery the option to refresh the hash key as well so if they have shared with users and someone posts the public URL or something they can lock it down again.

Wade
Yeah, that's already a planned feature :)So you're suggesting I allow mysite.com/hash AND mysite.com/album/id/hash? The idea with only using the former was that I could stuff the hash into a session key, redirect like I'd need to anyway and hide it from the URL. I could redirect to the same page from the album but without the hash too... but I'm just not entirely sure of the added benefit?
Mark
That was actually my fault, I see above that you explained the hash already has that. I was thinking more like "permission" where the hash just dictates what album you could see.You are right in your comment, if the hash contains that information you don't need the extra step.
Wade
A: 

Okay, here's what I'm doing:

$result = mysql_safe_query('SELECT * FROM short_urls WHERE short=%s', $_GET['p']);
if(mysql_num_rows($result)> 0) {
 $url = mysql_fetch_assoc($result);
    $_SESSION['permissions'][$url['long']] = true;
    redirect($url['long']);
}

This saves the permission in a session variable and redirects the user to the proper page. Then on the photo page I do this:

if(array_key_exists('/photo/'.$photo_id, $_SESSION['permissions'])
    || array_key_exists('/album/'.$photo['album_id'], $_SESSION['permissions'])) {
    $can_see = true;
}

But I'm still not sure how I feel about this. What if at some point down the road I want my short URL to point to /photo/5/some_other_param? It will redirect the user correctly, but it will store the wrong variable in the permissions array. I guess what I should do is add another column to my short_urls table that specifies what exactly it should put into the permissions array, eh?


Actually I like this solution better anyway I think. That way not every short URL even has to set permissions. New code:

if(isset($url['perm_key'])) $_SESSION['permissions'][$url['perm_key']] = true;
Mark