我想知道,如何将Codeigniter的表单验证与Web服务一起使用?我正在使用 REST 和 cURL 与 Web 服务连接,并尝试在登录页面上使用表单验证。当用户名或密码字段为空时,我可以让它返回错误,但不确定如何使用它来检查密码是否匹配。我的 cUrl 代码如下:
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_HEADER, false);
curl_setopt($ch, CURLOPT_HTTPHEADER, array("X-DocuSign-Authentication: $header"));
curl_setopt($ch, CURLOPT_UNRESTRICTED_AUTH, 1);
$output = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
$this->form_validation->set_rules('username', 'USERNAME', 'required|is_unique[username]');
$this->form_validation->set_rules('password', 'PASSWORD', 'required|matches[password]');
if ($this->form_validation->run() == FALSE) {
curl_close($ch);
$this->load->view('error_login');
} else {
$response = json_decode($output, true);
$accountId = $response["loginAccounts"][0]["accountId"];
$baseUrl = $response["loginAccounts"][0]["baseUrl"];
$userName = $response["loginAccounts"][0]["userName"];
curl_close($ch);
$username = $userName;
$docusignURL = $baseUrl;
$docHeader = $header;
$loggedIn = array('is_logged_in' => true);
$this->session->set_userdata('username', $username);
$this->session->set_userdata('docusignURL', $docusignURL);
$this->session->set_userdata('docHeader', $docHeader);
$this->session->set_userdata($loggedIn);
redirect('/create_envelope', 'refresh');
}
现在它返回两个错误通知,"未定义的偏移量:1"和"未定义的属性:登录::$db"。后者是因为,我假设,我没有使用模型连接到任何数据库。任何有用的建议都将非常出色。
编辑:所以我尝试了回调路由,但我收到500错误。这是我到目前为止的整个控制器代码:
<?php
class Login extends CI_Controller {
function index() {
$this->load->view('al_login');
}
function authenticate(){
$post = $this->input->post();
extract($post);
$integratorKey = '****-********-****-****-****-************';
$header = "<DocuSignCredentials><Username>" . $username . "</Username><Password>" . $password . "</Password><IntegratorKey>" . $integratorKey . "</IntegratorKey></DocuSignCredentials>";
$url = "https://demo.docusign.net/restapi/v2/login_information";
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_HEADER, false);
curl_setopt($ch, CURLOPT_HTTPHEADER, array("X-DocuSign-Authentication: $header"));
curl_setopt($ch, CURLOPT_UNRESTRICTED_AUTH, 1);
$output = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
$response = json_decode($output, true);
$accountId = $response["loginAccounts"][0]["accountId"];
$baseUrl = $response["loginAccounts"][0]["baseUrl"];
$userName = $response["loginAccounts"][0]["userName"];
curl_close($ch);
$username = $userName;
$docusignURL = $baseUrl;
$docHeader = $header;
$loggedIn = array('is_logged_in' => true);
$this->session->set_userdata('username', $username);
$this->session->set_userdata('docusignURL', $docusignURL);
$this->session->set_userdata('docHeader', $docHeader);
$this->session->set_userdata($loggedIn);
$this->form_validation->set_rules('username', 'USERNAME', 'required');
$this->form_validation->set_rules('password', 'PASSWORD', 'required|callback_password_check');
if ($this->form_validation->run() == FALSE) {
$this->load->view('al_login');
} else {
$this->load->view('/create_envelope');
}
}
function password_check($str){
// send the user name to the service
if ( $this->authenticate($str) == true ) {
return true;
} else {
// customize the message with something
$this->form_validation->set_message('password_check', 'The %s is incorrect. Please try again');
return false;
}
}
}
我是REST,cURL和Codeigniter的新手,所以我的知识可以提供帮助。到目前为止,感谢你们俩。知道为什么我会收到 500 个错误吗?
新编辑: @Petre 因此,这是我们网络服务的响应:
Array (
[loginAccounts] => Array (
[0] => Array (
[name] => ********
[accountId] => *******
[baseUrl] => https://demo.docusign.net/restapi/v2/accounts/*******
[isDefault] => true
[userName] => **** ********
[userId] => ********-****-****-****-************
[email] => ****@******.com
[siteDescription] =>
)
)
)
似乎不是那种东西。
我在上面的代码中看到的主要问题是意大利面条因素,因为它阻止了对重要内容的查看。你想做什么?
- 显示带有提交按钮的表单。
- 从某个 URL/操作的表单接收数据。
- 验证表单。
- 如果数据无效,则显示表单并通知用户错误。
- 如果数据有效,请将数据发送到 Web 服务。
- 如果数据无效,请将用户重定向到表单并通知无效的用户/通行证组合。
- 如果数据有效,请在会话中保存一些数据以存储身份验证因素。
我们不要关注步骤 1 和 2,因为它们很可能已经在工作了。因此,让我们讨论表单验证。
$this->form_validation->set_rules('username', 'USERNAME', 'required|is_unique[username]');
$this->form_validation->set_rules('password', 'PASSWORD', 'required|matches[password]');
请记住,在此阶段,您正在验证表单,您无权访问关系数据库(因为数据是通过 Web 服务检索的,理想情况下在不同的服务器上检索(,您只想确保表单中的用户名和密码字段已填写。您只想确保它们被提供,并且可能具有特定的长度。让我们重新审视上面的代码。
$this->form_validation->set_rules('username', 'USERNAME', 'required|min_length[5]');
$this->form_validation->set_rules('password', 'PASSWORD', 'required|min_length[5]');
请记住,您只是在此阶段验证通过表单收到的数据 - 您不关心Web服务端发生的事情,该端担心提供该服务。
接下来,我们需要看看在表单验证失败或成功的情况下我们要做什么。我们目前的基本计划是:
if ($this->form_validation->run() == FALSE) {
//Username or password field were not provided or they were too short.
//Render form and display errors.
} else {
//Username and password field have been provided and they were within the length requirements.
//Call cURL library and call webservice.
//Retrieve webservice response.
if ($response == 'valid') {
//Webservice told us that username/password combo was right!
//Store some data in the session to authenticate user.
} else {
//Webservice response told us that username/password combo is not right.
//Render login form and inform user that user/pass combo were not correct.
}
}
我们现在只有评论——这是我们的计划,对吧?我们已经验证了我们从用户那里得到了一些正确的输入(输入清理(,现在我们想看看这些值是否正确。
但是现在,与其添加所有这些代码块,不如让我们做一些好的设计并使用模型!
if ($this->form_validation->run() == FALSE) {
//Username or password field were not provided or they were too short.
$this->load->view('myview');
} else {
//Username and password field have been provided and they were within the length requirements.
$username = $this->input->post('username');
$password = $this->input->post('password');
// Make call to webservice with parameters to check if the credentials are correct or not.
$response = $this->muser->checkLoginCredentials($username, $password)
if ($response->valid == 'valid') {
//Webservice told us that username/password combo was right!
$this->muser->storeLoginCredentials($response->fullName, $response->email, $response->username);
} else {
//Webservice response told us that username/password combo is not right.
$data['error'] = 'Invalid username/password combination';
$this->load->view('myview', $data);
}
}
我们的代码现在非常清晰!我们只需要创建 Muser 模型并确保它有两种方法:
- checkLoginCredentials:使用我们知道已清理的用户名和密码调用 Web 服务并检索响应。
- storeLoginCredentials:给定来自 Web 服务响应的一些参数,将该数据存储在会话中。
现在,为什么你的代码第一次不起作用?
- 您对用户名有 is_unique[用户名] 规则,但您没有与用于的数据库进行交互。您不是在检查用户名是否唯一,您只是希望网络服务告诉您登录凭据是否正确。
- 你还有一个关于密码的匹配[密码]规则,它不执行任何操作。您可能正在考虑拥有一个_password_confirmation_字段,是的,该规则将适用于那里。
很抱歉写得太长,希望它有所帮助并在此过程中澄清更多事情。如果我能提供更多信息,请发表评论,我会更新答案!
我认为你想要的被命名为"回调",见这里 http://ellislab.com/codeigniter/user-guide/libraries/form_validation.html#callbacks
首先确保你的 curl rest 代码正常工作。只需让它回显真假或简单的东西,以便您验证其结果。然后将其集成到您的回调中。
从手册中他们命名的示例开始:callback_username_check
function username_check($str){
// send the user name to the service
if ( $this->_sendUserName($str) == true )
{ return true ; }
else{
// customize the message with something
$this->form_validation->set_message('username_check', 'The %s is incorrect so have another cup of coffee and try again');
return false ; }
}
请注意,我正在调用一个单独的方法,该方法仅包含 rest/curl 代码。 这样,如果您的服务发生更改,则不必更改回调。
编辑-我只是使用了"用户名"的示例,以使其与指南中的示例保持一致。
如果您需要将用户名和密码都发送到服务,我的建议是对用户名进行基本验证,然后对密码进行回调。 因此,密码的值来自回调,然后从中获取用户名的值
$username = $this->input->post('username', TRUE);
您可以在验证之前或之后的任何地方使用 $this->input->post((。 TRUE XSS 会清理它。
通常,如果有人弄乱了用户名和密码,密码不正确。 因此,通过使用回调进行验证,如果失败 - 当您再次显示表单时 - 用户名仍将被填写。如果您从服务中获取有关失败原因的信息 - 您可以自定义使用该信息显示的错误消息。