Hi everyone,
I am using Yii-user and Facebook login part from the (yii-user-management)
Now i have finished writing the code, however, each time I click Facebook login button. After I logged in to Facebook,
I still need to login with my site.(and nothing happens to my database) That means, I guess…something went wrong with my user identity …
Here are my codes…any hints?
LoginController:
<?php
class LoginController extends Controller
{
public $defaultAction = 'login';
public function actionFacebook() {
Yii::app()->user->logout();
Yii::import('application.modules.user.vendors.facebook.*');
$facebook = new Facebook(Yii::app()->params['facebookApi'], Yii::app()->params['facebookSecretCode']);
$fb_uid = $facebook->getUser();
if($fb_uid){
$user = User::model()->findByAttributes(array('facebook_id' => $fb_uid));
if($user === NULL){
// Save new facebook user to database
$user = new User;
$user->facebook_id = $fb_uid;
$user->status = User::STATUS_ACTIVE;
$user->createtime = time();
$user->lastvisit = time();
$user->superuser = 0;
if($user->save(false)){
$profile = new Profile;
$profile->user_id=$user->id;
$profile->save(false);
}
}
$identity=new UserIdentity($fb_uid, $user->id);
$identity->authenticate(true);
switch($identity->errorCode)
{
case UserIdentity::ERROR_NONE:
$duration= 3600*24*30; // 30 days
Yii::app()->user->login($identity,$duration);
$this->redirect(Yii::app()->controller->module->returnUrl);
break;
case UserIdentity::ERROR_STATUS_NOTACTIV:
$user->addError("status",UserModule::t("You account is not activated."));
break;
case UserIdentity::ERROR_STATUS_BAN:
$user->addError("status",UserModule::t("You account is blocked."));
break;
case UserIdentity::ERROR_PASSWORD_INVALID:
$user->addError("password",UserModule::t("Password is incorrect."));
break;
}
$this->render('facebook', array('user' => $user));
}
else
{
$this->redirect(Yii::app()->controller->module->returnLogoutUrl);
}
}
/**
* Displays the login page
*/
public function actionLogin()
{
if (Yii::app()->user->isGuest) {
$model=new UserLogin;
// if called without specific returnUrl, set it to the previous page
if (!isset($_POST['UserLogin']) && Yii::app()->user->returnUrl === Yii::app()->request->scriptUrl)
{
if (isset($_SERVER['HTTP_REFERER']))
{
Yii::app()->user->setReturnUrl($_SERVER['HTTP_REFERER']);
}
}
// collect user input data
if(isset($_POST['UserLogin']))
{
$model->attributes=$_POST['UserLogin'];
// validate user input and redirect to previous page if valid
if($model->validate()) {
$this->lastViset();
$returnUrl = Yii::app()->user->returnUrl;
/*
if (strpos($returnUrl,'/index.php')!==false)
$returnUrl = Yii::app()->controller->module->returnUrl;
*/
Yii::app()->user->setReturnUrl('');
$this->redirect($returnUrl);
}
}
// display the login form
$this->render('/user/login',array('model'=>$model));
} else
$this->redirect(Yii::app()->controller->module->returnUrl);
}
private function lastViset() {
$lastVisit = User::model()->notsafe()->findByPk(Yii::app()->user->id);
$lastVisit->lastvisit = time();
$lastVisit->save();
}
}
UserIdentity:
class UserIdentity extends CUserIdentity
{
private $_id;
public $facebook_id;
const ERROR_EMAIL_INVALID=3;
const ERROR_STATUS_NOTACTIV=4;
const ERROR_STATUS_BAN=5;
/**
* Authenticates a user.
* The example implementation makes sure if the username and password
* are both 'demo'.
* In practical applications, this should be changed to authenticate
* against some persistent user identity storage (e.g. database).
* @return boolean whether authentication succeeds.
*/
public function authenticate($facebook = false)
{
// Validate facebook user
if($facebook){
Yii::import('application.modules.user.vendors.facebook.*');
require_once('Facebook.php');
$facebook = new Facebook(Yii::app()->params['facebookApi'], Yii::app()->params['facebookSecretCode']);
$fb_uid = $facebook->getUser();
$user=User::model()->findByAttributes(array('facebook_id'=> $fb_uid));
if($user===null){
$this->errorCode=self::ERROR_USERNAME_INVALID;
}
else if($user->status==0&&Yii::app()->controller->module->loginNotActiv==false)
$this->errorCode=self::ERROR_STATUS_NOTACTIV;
else if($user->status==-1)
$this->errorCode=self::ERROR_STATUS_BAN;
else {
$this->_id= $user->id;
$this->username = 'facebook';
$this->facebook_id = $fb_uid;
$this->errorCode=self::ERROR_NONE;
}
}
else
{
if (strpos($this->username,"@")) {
$user=User::model()->notsafe()->findByAttributes(array('email'=>$this->username));
} else {
$user=User::model()->notsafe()->findByAttributes(array('username'=>$this->username));
}
if($user===null)
if (strpos($this->username,"@")) {
$this->errorCode=self::ERROR_EMAIL_INVALID;
} else {
$this->errorCode=self::ERROR_USERNAME_INVALID;
}
else if(Yii::app()->getModule('user')->encrypting($this->password)!==$user->password)
$this->errorCode=self::ERROR_PASSWORD_INVALID;
else if($user->status==0&&Yii::app()->getModule('user')->loginNotActiv==false)
$this->errorCode=self::ERROR_STATUS_NOTACTIV;
else if($user->status==-1)
$this->errorCode=self::ERROR_STATUS_BAN;
else {
$this->_id=$user->id;
$this->username=$user->username;
$this->errorCode=self::ERROR_NONE;
}
return !$this->errorCode;
}
}
/**
* @return integer the ID of the user record
*/
public function getId()
{
return $this->_id;
}
}
Login form:-----only Facebook login part
<?php if (!Yii::app()->user->isGuest): ?>
<a href="<?php echo $this->createUrl('/user/auth/logout'); ?>" class="exit"><div></div>
<span>Logout</span>
</a>
<?php else: ?>
<fb:login-button perms="email,user_birthday,read_stream,publish_stream">
<span>Login to Facebook</span>
</fb:login-button>
<?php endif; ?>
Main config:
'params'=>array(
// this is used in contact page
'adminEmail'=>'no-reply@xxxxxxxxx.com',
'facebookApi' => 'xxxxxxxx',
'facebookSecretCode' => 'xxxxxxxxxxx',
),
Main layout: head and part codes:
<?php
Yii::import('application.modules.user.vendors.facebook.*');
$facebook = new Facebook(Yii::app()->params['facebookApi'], Yii::app()->params['facebookSecretCode']);
$fb_session = $facebook->getSession();
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:fb="http://www.facebook.com/2008/fbml">
<head>
....
...
</head>
<body>
<script>
window.fbAsyncInit = function() {
FB.init({
appId : '<?php echo xxxxxxxxxxxx; ?>',
});
// whenever the user logs in, we refresh the page
FB.Event.subscribe('auth.login', function() {
window.location.reload();
});
};
(function() {
var e = document.createElement('script');
e.src = document.location.protocol + '//connect.facebook.net/en_us/all.js';
e.async = true;
document.getElementById('fb-root').appendChild(e);
}());
</script>
...
...
</body>
This gives me auth type error…
Any ideas???