Generally speaking its a bad idea to just require a username password in the URL. Even if you're using SSL the URL and all its query parameters are not secure. If you want your feeds to be secure you could sign your requests with a private key using a hashing method such as HMAC-SHA1 or HMAC-SHA256. It works something like this.
The client needs two keys a public key and private key
PublicKey: ABCDJJJZ7BW9P0IH2NI3
PrivateKey: uFehWXvcM7mf==c8ZhOe3Fz+6d+zyQ2ja4A3De1N
Build a string from the verb, url, headers and body. It's recommended that you use SSL or include an Expire parameter to the url to prevent any hackers from effectively performing a replay attack. Make sure the date and host are included in the headers, the date is very important to make sure that the signature is always changing.
verb + \n
url + \n
header1: value + \n
header2: value + \n
body
Then the client signs the request using the hashing method described above. The pseudo code would look something like this.
base64encode(hmac-sha1($private_key, $string_to_sign))
The a header is appended to the request that contains the signature and public key
Authorization: $public_key:$signature
When the server received the message they retrieve the private key for the user using the public key received in the Authorization
header. Then the server performs the same algorithm and if the two signatures match the server knows that the request is authenticated because only a client with the correct public and private key can generate the same signature.
Here's a snipit of PHP code using this algorithm to sign a request.
public function sign() {
$time = time();
$date = gmdate(self::DATE_FORMAT_RFC2616, $time);
$verb = $this->payload['verb'];
$headers = $this->payload['headers'];
$query = $this->payload['query'];
$body = $this->payload['body'];
// Build the content string
$endpoint = $this->endpoint;
// Set the expiration time of the request
if($this->expires != 0 && !isset($query['Expires'])) {
$query['Expires'] = $time + ($this->expires * 60);
}
// Add the date to the request headers
$headers['date'] = $date;
// Add the host to the request headers
$headers['host'] = $this->host;
// Sort the query array and convert to querystring
uksort($query, 'strnatcasecmp');
$querystring = SUUtilities::to_query_string($query);
// Sort the headers to be sure they're in the right order
$modified_headers = array();
uksort($headers, 'strnatcasecmp');
// Concatinate the headers so the key and value are a single string
$include = array('date', 'host');
foreach($headers as $key => $value) {
if(in_array($key, $include) || substr($key, 0, 5) == "x-sbr") {
$modified_headers[] = preg_replace('/\s/', '', strtolower($key)).": ".$value;
}
}
// Build the string to sign
$string_to_sign = $verb.PHP_EOL
.$endpoint."?".$querystring.PHP_EOL
.implode(PHP_EOL, $modified_headers).PHP_EOL
.$body;
// Create the signature for the request
$signature = base64_encode(hash_hmac('sha1', $string_to_sign, $this->credentials['private_key'], true));
// Add the authorization header to the list of headers.
array_push($modified_headers, 'authorization: SBR '.$this->credentials['key'].':'.$signature);
$request = array();
$request['headers'] = $modified_headers;
$request['host'] = $this->host;
$request['endpoint'] = $endpoint;
$request['query'] = $query;
return $request;
}
Additional resources: