无法使用 user_id 以编程方式登录
Can`t login programmatically using user_id
我的用户模型中有 hybridRegister 回调。使用社交登录(例如 facebook)注册用户后,我会尝试查看他的电子邮件。如果数据库中存在电子邮件,我将停止注册并使用与此电子邮件相关的用户数据进行登录。
public function hybridRegister($provider, Hybrid_User_Profile $profile) {
$profile = (array)$profile;
$data = array(
'provider' => $provider,
'provider_uid' => $profile['identifier'],
//Extra fields here as needed like group_id, status etc.
);
if (strtolower($provider) === "vkontakte"){
$data['firstName'] = $profile['firstName'];
$data['lastName'] = $profile['lastName'];
//TODO make fetching picture to our server
$data['photo'] = $profile['photoURL'];
$data['email'] = $profile['emailVerified'];
}
if (strtolower($provider) === "facebook"){
$data['firstName'] = $profile['firstName'];
$data['lastName'] = $profile['lastName'];
//TODO выкачивать картинку на сервер
$data['photo'] = $profile['photoURL'];
$data['email'] = $profile['emailVerified'];
}
//Check if an email exists in our db. if yes, then login user else
// continue register...
$user = $this->existEmail($data);
if ($user){
**//AuthComponent::login throw error somewhere inside it**
AuthComponent::login($user);
return true;
}
else {
// если нет, то продолжаем регистрацию
$data['password'] = $this->generatePassword();
$data['username'] = $data['provider'] . $profile['identifier'];
$this->sendRegistrationEmail($data['email'], $data['username'], $data['password']);
$this->create();
return $this->save($data, false);
}
}
下面的错误:
Database Error
Error: SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '_setDefaults' at line 1
SQL Query: _setDefaults
Notice: If you want to customize this error message, create app/View/Errors/pdo_error.ctp
Stack Trace
CORE/Cake/Model/Datasource/DboSource.php line 460 → PDOStatement->execute(array)
CORE/Cake/Model/Datasource/DboSource.php line 426 → DboSource->_execute(string, array)
CORE/Cake/Model/Datasource/DboSource.php line 668 → DboSource->execute(string, array, array)
CORE/Cake/Model/Datasource/DboSource.php line 611 → DboSource->fetchAll(string, array, array)
CORE/Cake/Model/Model.php line 827 → DboSource->query(string, array, User)
CORE/Cake/Controller/Component/AuthComponent.php line 604 → Model->__call(string, array)
CORE/Cake/Controller/Component/AuthComponent.php line 604 → User->_setDefaults()
APP/Model/User.php line 250 → AuthComponent->login(array)
[internal function] → User->hybridRegister(string, Hybrid_User_Profile)
我查看了 authComponent 代码(一个登录函数)。有描述
/**
* Log a user in.
*
* **If a $user is provided that data will be stored as the logged in user.** If `$user` is empty or not
* specified, the request will be used to identify a user.
我不明白为什么我的代码无法运行。请告诉我。
回答
hybridRegister 函数的代码应该稍微更改一下。一旦在数据库中批准了用户电子邮件的存在,功能应该只是 return 用户。 HybridAuth 自己进行认证。代码如下:
//Check if an email exists in our db. if yes, then login user else
// continue register...
$user = $this->existEmail($data);
if ($user){
return $user;
}
我的错误是认为 hybridRegister 必须保存用户,否则 return 错误。但它可以从数据库中获取任何现有的用户记录,return它。
感谢@AD7six 和@burzum 的想法。 @AD7six 的回答对我来说是最有用的。
检查 SQL 错误和堆栈跟踪,这就是它显示的内容。
Error: SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '_setDefaults' at line 1
SQL Query: _setDefaults
CORE/Cake/Controller/Component/AuthComponent.php line 604 → User->_setDefaults()
很明显,您正在调用该模型对象中不存在的方法 _setDefaults() - 猜测它是一个模型。在 2.x 中,当它是模型对象时,不存在的方法会变成 SQL 查询。
然而,the AuthComponent itself implements that method。我猜它试图在模型而不是组件或类似的东西上调用该方法。调试愉快!
I have hybridRegister callback in my User model.
**//AuthComponent::login throw error somewhere inside it**
AuthComponent::login($user);
那是行不通的
登录函数不是静态的。
之所以不起作用,是因为in that function它调用了其他实例方法:
public function login($user = null) {
$this->_setDefaults(); # <-
该方法存在于 auth 组件中,但在静态调用时不存在于 $this
(您的用户模型)中。
正确解
登录用户是 "Controller" 逻辑;它属于控制器或组件,但 不是 模型。书中有一个 how to create a register function 的简单示例,应用于问题中的代码是:
public function register() {
if ($this->User->hybridRegister($this->request->data)) {
$id = $this->User->id;
$this->request->data['User'] = array_merge(
$this->request->data['User'],
array('id' => $id)
);
unset($this->request->data['User']['password']);
$this->Auth->login($this->request->data['User']);
return $this->redirect('/users/home');
}
}
其中 hybridRegiser
修改为 只有 负责创建用户记录(或不创建),如果需要则发送注册电子邮件,并返回 true/false 视情况而定。
我的用户模型中有 hybridRegister 回调。使用社交登录(例如 facebook)注册用户后,我会尝试查看他的电子邮件。如果数据库中存在电子邮件,我将停止注册并使用与此电子邮件相关的用户数据进行登录。
public function hybridRegister($provider, Hybrid_User_Profile $profile) {
$profile = (array)$profile;
$data = array(
'provider' => $provider,
'provider_uid' => $profile['identifier'],
//Extra fields here as needed like group_id, status etc.
);
if (strtolower($provider) === "vkontakte"){
$data['firstName'] = $profile['firstName'];
$data['lastName'] = $profile['lastName'];
//TODO make fetching picture to our server
$data['photo'] = $profile['photoURL'];
$data['email'] = $profile['emailVerified'];
}
if (strtolower($provider) === "facebook"){
$data['firstName'] = $profile['firstName'];
$data['lastName'] = $profile['lastName'];
//TODO выкачивать картинку на сервер
$data['photo'] = $profile['photoURL'];
$data['email'] = $profile['emailVerified'];
}
//Check if an email exists in our db. if yes, then login user else
// continue register...
$user = $this->existEmail($data);
if ($user){
**//AuthComponent::login throw error somewhere inside it**
AuthComponent::login($user);
return true;
}
else {
// если нет, то продолжаем регистрацию
$data['password'] = $this->generatePassword();
$data['username'] = $data['provider'] . $profile['identifier'];
$this->sendRegistrationEmail($data['email'], $data['username'], $data['password']);
$this->create();
return $this->save($data, false);
}
}
下面的错误:
Database Error
Error: SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '_setDefaults' at line 1
SQL Query: _setDefaults
Notice: If you want to customize this error message, create app/View/Errors/pdo_error.ctp
Stack Trace
CORE/Cake/Model/Datasource/DboSource.php line 460 → PDOStatement->execute(array)
CORE/Cake/Model/Datasource/DboSource.php line 426 → DboSource->_execute(string, array)
CORE/Cake/Model/Datasource/DboSource.php line 668 → DboSource->execute(string, array, array)
CORE/Cake/Model/Datasource/DboSource.php line 611 → DboSource->fetchAll(string, array, array)
CORE/Cake/Model/Model.php line 827 → DboSource->query(string, array, User)
CORE/Cake/Controller/Component/AuthComponent.php line 604 → Model->__call(string, array)
CORE/Cake/Controller/Component/AuthComponent.php line 604 → User->_setDefaults()
APP/Model/User.php line 250 → AuthComponent->login(array)
[internal function] → User->hybridRegister(string, Hybrid_User_Profile)
我查看了 authComponent 代码(一个登录函数)。有描述
/**
* Log a user in.
*
* **If a $user is provided that data will be stored as the logged in user.** If `$user` is empty or not
* specified, the request will be used to identify a user.
我不明白为什么我的代码无法运行。请告诉我。
回答
hybridRegister 函数的代码应该稍微更改一下。一旦在数据库中批准了用户电子邮件的存在,功能应该只是 return 用户。 HybridAuth 自己进行认证。代码如下:
//Check if an email exists in our db. if yes, then login user else
// continue register...
$user = $this->existEmail($data);
if ($user){
return $user;
}
我的错误是认为 hybridRegister 必须保存用户,否则 return 错误。但它可以从数据库中获取任何现有的用户记录,return它。
感谢@AD7six 和@burzum 的想法。 @AD7six 的回答对我来说是最有用的。
检查 SQL 错误和堆栈跟踪,这就是它显示的内容。
Error: SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '_setDefaults' at line 1
SQL Query: _setDefaults
CORE/Cake/Controller/Component/AuthComponent.php line 604 → User->_setDefaults()
很明显,您正在调用该模型对象中不存在的方法 _setDefaults() - 猜测它是一个模型。在 2.x 中,当它是模型对象时,不存在的方法会变成 SQL 查询。
然而,the AuthComponent itself implements that method。我猜它试图在模型而不是组件或类似的东西上调用该方法。调试愉快!
I have hybridRegister callback in my User model.
**//AuthComponent::login throw error somewhere inside it**
AuthComponent::login($user);
那是行不通的
登录函数不是静态的。
之所以不起作用,是因为in that function它调用了其他实例方法:
public function login($user = null) {
$this->_setDefaults(); # <-
该方法存在于 auth 组件中,但在静态调用时不存在于 $this
(您的用户模型)中。
正确解
登录用户是 "Controller" 逻辑;它属于控制器或组件,但 不是 模型。书中有一个 how to create a register function 的简单示例,应用于问题中的代码是:
public function register() {
if ($this->User->hybridRegister($this->request->data)) {
$id = $this->User->id;
$this->request->data['User'] = array_merge(
$this->request->data['User'],
array('id' => $id)
);
unset($this->request->data['User']['password']);
$this->Auth->login($this->request->data['User']);
return $this->redirect('/users/home');
}
}
其中 hybridRegiser
修改为 只有 负责创建用户记录(或不创建),如果需要则发送注册电子邮件,并返回 true/false 视情况而定。