bahti
bahti

Reputation: 636

How can i write php page that has an unpredictable url, thus only ones having the link view

I am trying to develop an application on android. The application is basically send the user's location information with the users it specified for a finite amount of time. It will be like Glympse.

I am doing this for a school project so don't have good hosts for the web. I am trying to use free ones. And i can not use their database systems to my own wishes. and inserting and fetching from the database continously will be a burden.

One other option coming to my mind, is to open up php page when the user wants to share hislocation. This page will continously communicate with the gps information. But as this pages should be specific to some people, they must have unique, unpredictable url. like the ones when have password recovery mails. Also i wonder how to make this pages exists for some time and disappears.

The page links will be sent to the shared users lately.

Upvotes: 1

Views: 173

Answers (3)

esserj
esserj

Reputation: 176

So what about storing any of the URI data is a session array and when a specific key is requested by the user use the received key and replace it by your actual URI stored in the $_SESSION array? when generating a uri you could have a method store it for you and return a replacing URI like so (note that you should have session already started that should not be part of this objects scope):

class URIStore{
    private $URIstoreID;
    private $SUPERSECRETSALT;
    private $storeName;

    const STORE_EXCEPTION_EXPIRED = 0;
    const STORE_EXCEPTION_CSRF = 1;

    public function __construct($storename){
        //retreive existing store ID so we can built on previous
        $this->URIstoreID = isset($_SESSION[$storename]['URIStoreID']) ? $_SESSION[$storename]['URIStoreID'] : 0;
        $this->SUPERSECRETSALT = 'jsf098u32rojwe092';//salt could be made random here
        $this->storename = $storename;
    }

    /**
     * stored the $uri data in a session for later retrieval through the returned key
     * @param mixed $uri - can be anything that you want, like a key value pair array
     * @return string
     */
    public function store($uri){
        $r = md5($this->URIStoreID.$this->SUPERSECRETSALT);
        $_SESSION[$this->storename][$r] = $uri;
        $this->URIStoreID++;
        $_SESSION[$this->storename]['URIStoreID'] = $this->URIStoreID;
        return $r;
    }

    /**
     * returns a previously stored URI item
     * @param string $key - the key you want to get the URI data for
     * @return mixed
     * @Throws Exception - when Store or Key doesnt exist
     */
    public function retrieve($key){
        if(!isset($_SESSION[$this->storename]){
            //the initial session has expired
            throw new Exception("URIStore [$this->storename] does not exists",self::STORE_EXCEPTION_EXPIRED);
        }
        elseif(!isset($_SESSION[$this->storename][$key]){
            //the requested key does not exist
            //could be CSRF attempt?
            throw new Exception("URIStore [$this->storename] does not contain this key",self::STORE_EXCEPTION_CSRF);
        }
        return $_SESSION[$this->storename][$key];
    }
}

the use the above you could do the following when building a URL

$store = new URIStore('URIStore');
$URL = SERVER_URL . 'yourscriptthathandlestherequest.php?key=' . $store->store(array('a'=>1,'b'=>23));

and when you retrieve a request you first get the actual data instead of get data like

$store = new URIStore('URIStore');
try{
    $data = $store->retrieve(@$_GET['key']);
}
catch(Exception $e){
    switch($e->getCode()){
        case URIStore::STORE_EXCEPTION_EXPIRED:
             //handle accordingly
             break;
        case URIStore::STORE_EXCEPTION_CSRF:
             //handle accordingly
             break;
    }
}

note that in your case GET is fine, for CRUD actions I would highly suggest using POST

the Session will expire when no requests are made for a while (depends on server settings) if you want different expirations for different items (still limited to the session expiration time as a maximum though) you would add another layer to the array that stores the uri and an additional timestamp that you have the URIStore::retrieve method compair against. and finally you could use multiple stores for different things if you wanted. so that you only use the one you expect on a certain page.

Upvotes: 1

AndreKR
AndreKR

Reputation: 33697

You need to have some kind of storage anyway, so I'm not goint into that.

The simplest solution is probably to have a unique number (Random unique ID or sequence number), suffix it with something like "read" and "write" and then secure it by building a hash over it and a secret key:

$secret = 'changeme';

$user_id = uniqid();

$public_url = 'page.php?user_id='.$user_id.
              '&access=r&check='.sha1($user_id.'r'.$secret);
$owner_url = 'page.php?user_id='.$user_id.
             '&access=w&check='.sha1($user_id.'w'.$secret);

Then you can check for them like this:

if ($_GET['check'] == sha1($_GET['user_id'].'r'.$secret))
{
    // show location
}

if ($_GET['check'] == sha1($_GET['user_id'].'w'.$secret))
{
    // do location update
}

If you don't want the user_id and access type to be visible in the URL you can use phpseclib to encrypt it instead of just securing it by sha1().

Upvotes: 0

toon81
toon81

Reputation: 868

You could give the users a link like: script.php?key=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx where the x's are an MD5. That MD5 could be the username and a "salt", like sort of a password. In other words, if $_GET['key'] matches md5($username . $super_secret_site_password) then you'll know that person is the real deal.

Upvotes: 1

Related Questions