Ali*_*Ali 3 openid zend-framework single-sign-on twitter-oauth
大家好我正在我的应用程序中集成使用facebook和twitter的标志.我打算稍后在线上包括其他关于提供者的标志.我实际上是从我在网上发现的一些开源代码构建的,但我想我在这里做了很多东西.
我的数据库结构如下:
用户ID | NAME | .... | EMAIL | PASSWORD
USER SIGNONS USER_ID | SIGNIN_TYPE | 登录ID
Whenevr任何人都可以通过使用Facebook或Twitter帐户登录来创建帐户 - 在用户登录表中输入一个条目,表明用户的签名类型为"facebook"或"twitter".
我已使用以下代码进行身份验证:
public function loginAction() {
$this->ajaxInit();
// get an instace of Zend_Auth
$auth = Zend_Auth::getInstance();
$p = $this->_getAllParams();
if(isset($p['redirectto'])){
$this->setRedirect($p['redirectto']);
}else{
$redirect = explode('?', $_SERVER['HTTP_REFERER']);
$this->setRedirect($redirect[0]);
}
// check if a user is already logged
// this checks if he is logged into an open id providor
/*if ($auth->hasIdentity()) {
return $this->_redirect('/index/index');
}*/
// if the user is not logged, the do the logging
// $openid_identifier will be set when users 'clicks' on the account provider
$openid_identifier = $this->getRequest()->getParam('openid_identifier', null);
if($this->getRequest()->getParam('rememberme', null)>0){
//Zend_Session::rememberMe(60 * 60 * 24 * 30);
}
// $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($redirect);
_log('inside here');
} else if ('https://www.facebook.com' == $openid_identifier) {
$adapter = $this->_getFacebookAdapter($redirect);
} else {
// for openid
$adapter = $this->_getOpenIdAdapter($openid_identifier);
// specify what to grab from the provider and what extension to use
// for this purpose
$toFetch = _config('openid', 'tofetch');
// for google and yahoo use AtributeExchange Extension
if ('https://www.google.com/accounts/o8/id' == $openid_identifier || 'http://me.yahoo.com/' == $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 loging
$result = $auth->authenticate($adapter);
// the following two lines should never be executed unless the redirection faild.
//$this->_helper->FlashMessenger('Redirection faild');
if(strstr($redirect, 'import')){
return $this->_redirect($redirect.'?cmsg=redirection-failure');
}
return $this->_redirect('/accounts/sign-in?error=redirection-failure');
}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 = _config('openid');
// for google and yahoo 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());
$options = array();
if ($ext) {
// for openId
$toStore['properties'] = $ext->getProperties();
$options['signin_type'] = 'open_id';
$toStore['signin_type'] = 'open_id';
$options['signin_id'] = $auth->getIdentity();
} else if ($code) {
// for facebook
$msgs = $result->getMessages();
$toStore['properties'] = (array) $msgs['user'];
$options['signin_type'] = 'facebook';
$toStore['signin_type'] = 'facebook';
$options['signin_id'] = $auth->getIdentity();
} else if ($oauth_token) {
$identity = $result->getIdentity();
$twitterUserData = (array) $adapter->verifyCredentials();
$toStore = array('identity' => $identity['user_id']);
if (isset($twitterUserData['status'])) {
$twitterUserData['status'] = (array) $twitterUserData['status'];
}
_log($twitterUserData);
$toStore['properties'] = $twitterUserData;
$options['signin_type'] = 'twitter';
$toStore['signin_type'] = 'twitter';
$options['signin_id'] = $identity['user_id'];
}
$user = _factory('people')->get(false, $options);
if(count($user)>0){
$user = array_pop($user);
$auth->getStorage()->write($user['account_email']);
return $this->_redirect($this->setRedirect);
//return $this->_redirect('/accounts/index');
}else{
$auth->getStorage()->write($toStore);
return $this->_redirect('/accounts/welcome');
}
} else {
return $this->_redirect('/index/index');
}
}
Run Code Online (Sandbox Code Playgroud)
}
我遇到的问题是我正在构建搜索你朋友的功能.我得到它与Facebook工作很容易.但是对于twitter我想使用Zend框架Zend_Service_Twitter代码.但是我发现我需要用户名才能登录并使用访问令牌 - 我发现我并不完全存储用户名.
在我的整个程序中只有一个地方进行身份验证,并且上面发布的代码可以访问 www.mysite.com/accounts/login
我的设计出了问题,但我无法告诉你什么.问题是,现在我无法登录Twitter帐户来检索任何用户详细信息.但是我可以通过Twitter登录,因为我的存储空间足以验证用户是否已使用Twitter帐户登录,并且相应的用户存在经过身份验证的帐户.除了那个用户登录后我无法访问用户的Twitter信息.
Facebook让我很容易,因为他们有专门的api来处理这个问题.如果我选择添加更多登录,这个问题肯定会在以后造成麻烦.
这里有任何帮助.上面的代码当然没有规定将acocunts与已经登录的用户相关联.
我应该如何构建我的登录代码和表.
我在这里使用zend框架.
根据我的理解,您的问题是在使用Twitter进行身份验证后,您不会存储用户名和access_token.我认为您应该能够获得此信息,然后将其存储如下(新位由comments/*new line*/标记):
} else if ($oauth_token) {
$identity = $result->getIdentity();
$twitterUserData = (array) $adapter->verifyCredentials();
$toStore = array('identity' => $identity['user_id']);
if (isset($twitterUserData['status'])) {
$twitterUserData['status'] = (array) $twitterUserData['status'];
}
_log($twitterUserData);
$toStore['properties'] = $twitterUserData;
$options['signin_type'] = 'twitter';
$toStore['signin_type'] = 'twitter';
/* new line */
$accessToken = $adapter->getAccessToken();
// $accessToken should be an instance of Zend_Oauth_Token_Access
// and it should contain screen_name, auth_token, etc.
// to make sure it contains what it should do:
// var_dump($accessToken); exit;
/* new line */
$toStore['access_token'] = $accessToken;
$options['signin_id'] = $identity['user_id'];
}
Run Code Online (Sandbox Code Playgroud)
因此,假设此处一切正常,您的$ accessToken应与您的身份一起存储.因此,要在其他地方使用它,您可以执行以下操作:
$auth = Zend_Auth::getInstance();
if ($auth->hasIdentity()) {
$identity = $auth->getIdentity();
$accessToken = $identity['access_token'];
// Zend_Service_Twitter can accept instance of Zend_Oauth_Token_Access
$twitter = new Zend_Service_Twitter(array(
'accessToken' => $accessToken
));
try {
// do whatever twitter operation you want (or is permitted) ,e.g.
$response = $twitter->status->update('My Great Tweets');
var_dump($response);
} catch (Exception $e) {
// In case something went wrong, e.g. our access token expired or is wrong
var_dump($e->getMessage());
}
}
Run Code Online (Sandbox Code Playgroud)
希望这有助于或至少提供一些线索该做什么.
| 归档时间: |
|
| 查看次数: |
442 次 |
| 最近记录: |