Drupal社区团队 2016-03-03 10:14
通过使用 Drupal 的 Session 认证方式,可以很轻松地基于 REST 服务器实现用户认证。这种方式通过管理会话cookie得以实现。不过在通过代码(例如使用 drupal_http_request() 或 curl)实现这项操作时,还需要进行一些额外的工作并手动设置请求头的cookie信息。cookie头看起来是这样的:
Cookie: SESS5913ad7ed2adf92cab1103dad2f5596c=213d28535c6972e16430a4e1e03ce7ea
以上信息由三部分组成:头部标识('Cookie'),会话名称('SESS5913ad7ed2adf92cab1103dad2f5596c'),以及会话ID('213d28535c6972e16430a4e1e03ce7ea')。值得庆幸的是,当你请求 Services 模块提供的 user/login 资源时,会话名和会话ID都会作为响应对象的一部分返回,所以把它组合起来和下一个请求一起发出去非常简单。一旦这样做了,下一个请求将会以授权用户的会话来执行。
下面是一些示例代码。要实现这样设置,需要一个启用了 user/login 和 node/retrieve 资源的 Drupal 站点,并且取消匿名用户“访问内容”的权限。
示例:Drupal 7
测试环境 7.x-3.0-rc1
<?php
$base_url = 'http://localhost/test_endpoint';
$data = array(
'username' => 'admin',
'password' => 'password',
);
$data = drupal_json_encode($data);
$options = array(
'headers' => array(
'Content-Type' => 'application/json',
),
'method' => 'POST',
'data' => $data
);
$response = drupal_http_request($base_url . '/user/login', $options);
$data = json_decode($response->data);
// Check if login was successful
if ($response->code == 200) {
// Now recycle the login cookie we received in the first request
$options['headers']['Cookie'] = $data->session_name . '=' . $data->sessid;
// Get info about a user
$data = array();
$options['data'] = http_build_query($data, '', '&');
$options['method'] = 'GET';
$response = drupal_http_request($base_url . '/user/32', $options);
}
?>
Drupal 7 中 drupal_http_request() 函数的参数有所变化。Services 3 也使用了不同的用户登录变量,需要通过POST方式进行获取。
示例:Drupal 6
测试环境 6.x-3.0-beta2
<?php
// This is the base URL for our installation
$base_url = 'http://domain.com/test_endpoint/';
// necessary or the response is empty:
$headers = array('Content-Type' => 'application/x-www-form-urlencoded');
// Login
$data = array(
'username' => 'admin',
'password' => 'password',
);
$data = http_build_query($data, '', '&');
$response = drupal_http_request($base_url . '/user/login', $headers, 'POST', $data);
$data = json_decode($response->data);
//$headers['Cookie'] = "$data->session_name=$data->sessid";
$response = drupal_http_request($base_url . '/node/21.json', $headers); // replace this with a node id on your system
print_r(json_decode($response->data));
?>
注意上述代码中设置 cookie 头的那行代码是被注释掉的。当你在运行这段代码尝试访问节点21时, ,你被提示“拒绝访问” 。 取消注释之后再运行一次。OK了!可以将会话名称和会话ID保存在某个地方,以方便在后续请求中使用。
在 Drupal 7 中可以通过 XMLRPC 执行相同的验证调用。但在 Drupal 6中,则必须要先打上这个内核补丁。
请注意,大多数 Cookie 都有会过期或只能在一个会话中使用。你应该遵守这些限制,并构建系统时考虑到它们(本方的示例代码并不包括这些内容。)
(译注:因为安全性问题,较新版本的 Service 模块要求请求时添加 CRSF Token 才可成功执行)