I have the error of
[12-Jul-2011 11:05:43] PHP Fatal error: Call to a member function isValid() on a non-object in /usr/share/pear/ZendFramework/1.11.7/library/Zend/Auth.php on line 127
coming up in my code. I've been trying to figure out where the problem exists and been doing research on it, but have had no success.
<?php
class UserController extends Zend_Controller_Action
{
/**
* Application keys from appkeys.ini
*
* @var ZendX_Config
*/
protected $_keys;
public function init()
{
$appkeys = new ZendX_Config_Ini(APPLICATION_PATH . '/configs/appkeys.ini', APPLICATION_ENV);
Zend_Registry::set('keys',$appkeys);
$this->_keys = Zend_Registry::get('keys');
}
public function indexAction()
{
// action body
}
public function loginAction()
{
// get an instace of Zend_Auth
$auth = Zend_Auth::getInstance();
// check if a user is already logged
if ($auth->hasIdentity())
{
$this->_helper->FlashMessenger('It seems you are already logged into the system ');
return $this->_redirect('/index/index');
}
// if the user is not logged, then do the logging
// $openid_identifier will be set when users 'clicks' on the account provider
$openid_identifier = $this->getRequest()->getParam('openid_identifier', null);
// $openid_mode will be set after first query to the openid provider
$openid_mode = $this->getRequest()->getParam('openid_mode', null);
// this one will be set by facebook connect
$code = $this->getRequest()->getParam('code', null);
// while this one will be set by twitter
$oauth_token = $this->getRequest()->getParam('oauth_token', null);
// do the first query to an authentication provider
if ($openid_identifier)
{
if ('https://www.twitter.com' == $openid_identifier)
{
$adapter = $this->_getTwitterAdapter();
}
else if ('https://www.facebook.com' == $openid_identifier)
{
$adapter = $this->_getFacebookAdapter();
}
else
{
// for openid
$adapter = $this->_getOpenIdAdapter($openid_identifier);
// specify what to grab from the provider and what extension to use
// for this purpose
$toFetch = $this->_keys->openid->tofetch->toArray();
// for google use AtributeExchange Extension
if ('https://www.google.com/accounts/o8/id' == $openid_identifier)
{
$ext = $this->_getOpenIdExt('ax', $toFetch);
}
else
{
$ext = $this->_getOpenIdExt('sreg', $toFetch);
}
$adapter->setExtensions($ext);
}
// here a user is redirect to the provider for logging
$result = $auth->authenticate($adapter);
// the following two lines should never be executed unless the redirection fails.
//$this->_helper->FlashMessenger('Redirection failed');
// return $this->_redirect('/index/');
}
else if ($openid_mode || $code || $oauth_token)
{
// this will be exectued after provider redirected the user back to us
if ($code)
{
// for facebook
$adapter = $this->_getFacebookAdapter();
}
else if ($oauth_token)
{
// for twitter
$adapter = $this->_getTwitterAdapter()->setQueryData($_GET);
}
else
{
// for openid
$adapter = $this->_getOpenIdAdapter(null);
// specify what to grab from the provider and what extension to use
// for this purpose
$ext = null;
$toFetch = $this->_keys->openid->tofetch->toArray();
// for google use AtributeExchange Extension
if (isset($_GET['openid_ns_ext1']) || isset($_GET['openid_ns_ax']))
{
$ext = $this->_getOpenIdExt('ax', $toFetch);
}
else if (isset($_GET['openid_ns_sreg']))
{
$ext = $this->_getOpenIdExt('sreg', $toFetch);
}
if ($ext)
{
$ext->parseResponse($_GET);
$adapter->setExtensions($ext);
}
}
$result = $auth->authenticate($adapter);
if ($result->isValid())
{
$toStore = array('identity' => $auth->getIdentity());
if ($ext)
{
// for openId
$toStore['properties'] = $ext->getProperties();
}
else if ($code)
{
// for facebook
$msgs = $result->getMessages();
$user = ($msgs['user']);
$hometown = ($user['hometown']['name']);
$location = ($user['location']['name']);
$sports = ($user['sports']['0']['name']);
$favAth = ($user['favorite_athletes']['0']['name']);
$user['hometown'] = $hometown;
$user['location'] = $location;
$user['sports'] = $sports;
$user['favorite_athletes'] = $favAth;
$toStore['properties'] = $user;
$userID = $user['id'];
$ogurl = "******";
define(FACEBOOK_APP_ID, "*****");
define(FACEBOOK_SECRET, "******");
$message = "Hello World!";
$link = '****';
$name = '****';
$picture = '****';
$access_token_url = "https://graph.facebook.com/oauth/access_token";
$parameters = "grant_type=client_credentials&client_id=" . FACEBOOK_APP_ID .
"&client_secret=" . FACEBOOK_SECRET;
$access_token = file_get_contents($access_token_url . "?" . $parameters);
$apprequest_url = "https://graph.facebook.com/{$userID}/feed";
$parameters = "?" . $access_token . /*"&message=" .
urlencode($message) . */"&picture=" .
urlencode($picture) . "&link=" . urlencode($link) ."&name=" .
urlencode($name) ."&id=" . $ogurl . "&method=post";
$myurl = $apprequest_url . $parameters;
$post = file_get_contents($myurl);
// output the post id
// echo "post_id" . $result;
}
else if ($oauth_token)
{
// for twitter
$identity = $result->getIdentity();
// get user info
$twitterUserData = (array) $adapter->verifyCredentials();
$toStore = array('identity' => $identity['user_id']);
if (isset($twitterUserData['status']))
{
$twitterUserData['status'] = (array) $twitterUserData['status'];
}
$toStore['properties'] = $twitterUserData;
//Tweet
$oAuthToken = '****';
$oAuthSecret = '****';
// create a new instance
$tweet = new TwitterOAuth($consumerKey, $consumerSecret, $oAuthToken, $oAuthSecret);
//send a tweet
$tweet->post('statuses/update', array('status' => 'Hello World'));
}
$auth->getStorage()->write($toStore);
$this->_helper->FlashMessenger('Successful authentication');
return $this->_redirect('/index/index');
}
else
{
$this->_helper->FlashMessenger('Failed authentication');
$this->_helper->FlashMessenger($result->getMessages());
return $this->_redirect('/index/index');
}
}
}
public function logoutAction()
{
$auth = Zend_Auth::getInstance();
$auth->clearIdentity();
$this->_helper->FlashMessenger('You were logged out');
return $this->_redirect('/index/index');
}
/**
* Get My_Auth_Adapter_Facebook adapter
*
* @return My_Auth_Adapter_Faceboo开发者_如何转开发k
*/
protected function _getFacebookAdapter()
{
extract($this->_keys->facebook->toArray());
return new My_Auth_Adapter_Facebook($appId, $secret, $redirecturi, $scope);
}
/**
* Get My_Auth_Adapter_Oauth_Twitter adapter
*
* @return My_Auth_Adapter_Oauth_Twitter
*/
protected function _getTwitterAdapter()
{
extract($this->_keys->twitter->toArray());
return new My_Auth_Adapter_Oauth_Twitter(array(), $appid, $secret, $redirecturi, $token, $authSecret);
}
/**
* Get ZendX_Auth_Adapter_OpenId adapter
*
* @param string $openid_identifier
* @return ZendX_Auth_Adapter_OpenId
*/
protected function _getOpenIdAdapter($openid_identifier = null)
{
$adapter = new ZendX_Auth_Adapter_OpenId($openid_identifier);
$dir = APPLICATION_PATH . '/tmp';
if (!file_exists($dir))
{
if (!mkdir($dir))
{
throw new Zend_Exception("Cannot create $dir to store tmp auth data.");
}
}
$adapter->setStorage(new Zend_OpenId_Consumer_Storage_File($dir));
return $adapter;
}
/**
* Get Zend_OpenId_Extension. Sreg or Ax.
*
* @param string $extType Possible values: 'sreg' or 'ax'
* @param array $propertiesToRequest
* @return Zend_OpenId_Extension|null
*/
protected function _getOpenIdExt($extType, array $propertiesToRequest)
{
$ext = null;
if ('ax' == $extType)
{
$ext = new My_OpenId_Extension_AttributeExchange($propertiesToRequest);
}
elseif ('sreg' == $extType)
{
$ext = new Zend_OpenId_Extension_Sreg($propertiesToRequest);
}
return $ext;
}
}
And the Facebook Adapter looks like...
<?php
/**
* Description of Facebook
*
* @link http://www.krotscheck.net/2010/08/21/zend_auth_adapter_facebook.html
* @author Michael Krotscheck
*/
class My_Auth_Adapter_Facebook implements Zend_Auth_Adapter_Interface
{
/**
* The Authentication URI, used to bounce the user to the facebook redirect uri.
*
* @var string
*/
const AUTH_URI = 'https://graph.facebook.com/oauth/authorize?client_id=%s&redirect_uri=%s';
/**
* The token URI, used to retrieve the OAuth Token.
*
* @var string
*/
const TOKEN_URI = 'https://graph.facebook.com/oauth/access_token';
/**
* The user URI, used to retrieve information about the user.
*
* @var string
*/
const USER_URI = 'https://graph.facebook.com/me';
/**
* The application ID
*
* @var string
*/
private $_appId = null;
/**
* The application secret
*
* @var string
*/
private $_secret = null;
/**
* The authentication scope (advanced options) requested
*
*
*/
private $_scope;
/**
* The redirect uri
*
* @var string
*/
private $_redirectUri = null;
/**
* Constructor
*
* @param string $appId the application ID
* @param string $secret the application secret
* @param array $scope the application scope
* @param string $redirectUri the URI to redirect the user to after successful authentication
*/
public function __construct($appId, $secret, $redirectUri, $scope)
{
$this->_appId = $appId;
$this->_secret = $secret;
$this->_scope = $scope;
$this->_redirectUri = $redirectUri;
}
/**
* Sets the value to be used as the application ID
*
* @param string $appId The application ID
* @return My_Auth_Adapter_Facebook Provides a fluent interface
*/
public function setAppId($appId)
{
$this->_appId = $appId;
return $this;
}
/**
* Sets the value to be used as the application secret
*
* @param string $secret The application secret
* @return My_Auth_Adapter_Facebook Provides a fluent interface
*/
public function setSecret($secret)
{
$this->_secret = $secret;
return $this;
}
/**
* Sets the value to be used as the application scope (array())
*
* @param string $scope The application scope
* @return My_Auth_Adapter_Facebook Provides a fluent interface
*/
public function setApplicationScope($scope)
{
$this->_scope = $scope;
return $this;
}
/**
* Sets the redirect uri after successful authentication
*
* @param string $redirectUri The redirect URI
* @return My_Auth_Adapter_Facebook Provides a fluent interface
*/
public function setRedirectUri($redirectUri)
{
$this->_redirectUri = $redirectUri;
return $this;
}
/**
* Authenticates the user against facebook
* Defined by Zend_Auth_Adapter_Interface.
*
* @throws Zend_Auth_Adapter_Exception If answering the authentication query is impossible
* @return Zend_Auth_Result
*/
public function authenticate()
{
// Get the request object.
$frontController = Zend_Controller_Front::getInstance();
$request = $frontController->getRequest();
// First check to see whether we're processing a redirect response.
$code = $request->getParam('code');
if ( empty ($code ) )
{
// Create the initial redirect
$loginUri = sprintf(My_Auth_Adapter_Facebook::AUTH_URI , $this->_appId, $this->_redirectUri);
if ( !empty($this->_scope) )
{
$loginUri .= "&scope=" . $this->_scope;
}
header('Location: ' . $loginUri );
}
else
{
// Looks like we have a code. Let's get an access token
$client = new Zend_Http_Client( My_Auth_Adapter_Facebook::TOKEN_URI );
$client->setParameterGet('client_id', $this->_appId);
$client->setParameterGet('client_secret', $this->_secret);
$client->setParameterGet('code', $code);
$client->setParameterGet('redirect_uri', $this->_redirectUri);
$result = $client->request('GET');
$params = array();
parse_str($result->getBody(), $params);
// Retrieve the user info
$client = new Zend_Http_Client(My_Auth_Adapter_Facebook::USER_URI );
$client->setParameterGet('client_id', $this->_appId);
$client->setParameterGet('access_token', $params['access_token']);
$result = $client->request('GET');
$user = json_decode($result->getBody(), true);
return new Zend_Auth_Result( Zend_Auth_Result::SUCCESS, $user['id'], array('user'=>$user, 'token'=>$params['access_token']) );
}
}
}
Any help on this issue would be much appreciated. Thanks in advance.
You forgot to return an Zend_Auth_Result
-object, when My_Auth_Adapter_Facebook::authenticate()
fails.
You should check that $result
is an actual object before calling isValid()
.
精彩评论