如何验证使用我的web服务的网站


How to authenticate websites that use my web service

为了简化问题,假设我有一个PHP web服务,它显示服务器的当前日期时间,并且该服务以任意平均值、纯文本、JSON对象等形式输出其数据。我有一个网站的列表,只应该能够使用此服务,而任何其他网站不应该有访问此服务。

问题是:我的服务器上的PHP如何能够区分来自www.allowed-website.com的请求,然后给它访问权并禁止访问www.anyother-website.com

一个简单的方法是用私钥实现签名请求,这样你就不需要预认证,凭证不会通过网络发送,最重要的是,它不可能做中间人攻击,攻击者只能重新发送确切的请求。

服务器和客户端都知道私钥,然后用它来验证和签名请求。

<?php
$public_key = hash('sha256', 'Client identification, call it public key.');
$private_key = hash('sha256', 'A secret only the server and client know');
/**
 * Packet for POST request
 */
$packet = http_build_query(array(
    'do' => 'foo',
    'body' => 'bar'
));
/**
 * Sign the packet with private key - which returns valid request token
 */
$token = hash_hmac('sha256', $packet, $private_key);

/**
 * Build the x-headers, with public key and request token
 */
$header = array(
    'X-Public: ' . $public_key,
    'X-Token: ' . $token
);
//..do curl request with headers
?>

然后在服务器端解析x-headers,根据公钥查找客户端,然后使用私钥重新hash_hmac请求,如果它与令牌匹配,则请求通过身份验证。

<?php
//or do a lookput on your API clients table ;p based on the public key
$public_key = hash('sha256', 'Client identification, call it public key.');
$private_key = hash('sha256', 'A secret only the server and client know');
$packet = http_build_query(array(
    'do' => $_POST['do'],
    'body' => $_POST['body']
));
if (hash_hmac('sha256', $packet, $private_key) == $headers['X-Token']){
    //valid request
}
?>

浩瀚的主题。您有许多选项,其中可能包括:

  • 要求调用服务器包含凭据(用户id和密码/密钥,或者如果不重要则只是用户id)

  • 请求调用服务器包含凭据(某些用户id)和签名

  • 按IP地址过滤

  • 使用SSL客户机证书

您可能希望了解现有web服务如何执行身份验证/授权。许多(Facebook, Google+, Twitter等)使用OAuth。其他(例如Amazon)使用签名。我现在太懒了,不想考虑其他事情:-)

相关文章: