CakePHP - 保存一个会话变量会删除另一个会话变量
我在 CakePHP 中使用会话变量来存储我的相关用户 Twitter 和 Facebook 数据,当用户登录时,如果他链接了他的 Twitter 和 FB 帐户,则此信息将保存在我自己的用户数据旁边的会话变量中。
我有一个屏幕,用户可以在其中链接和取消链接所述社交网络数据,问题如下:
假设我连接了两个网络,我决定与 Facebook 断开连接,Facebook 的会话变量被删除。现在我希望重新连接到 Facebook,我单击“连接”按钮,Facebook 数据已保存,但由于某种原因它删除了 Twitter 变量。
我的流程的工作方式如下:
1)用户单击连接按钮。 2) 用户被引导至社交网络身份验证。 3) 用户被引导到一个函数,该函数获取所需的数据,将其保存在名为 NetworkData 的会话变量中,然后被引导回他单击按钮的页面。 4) 提取 NetworkData,将其设置为会话中的相应社交网络(Facebook 或 Twitter)并从会话中删除。
代码如下:
这是用户登录 Twitter 或 FB 后定向的函数:
function retrieve_network($page) {
$networkData = null;
$this->autoRender = false;
$this->layout = 'ajax';
if(isset($_GET['oauth_token'])) {
$token = $this->TwitterHelper->setOAuthToken($_GET['oauth_token']);
$userinfo = $this->TwitterHelper->getTwitterUserInfo();
$networkData = array(
'TwitterData' => array(
'username' => $userinfo['username'],
'name' => $userinfo['name'],
'token' => $token->oauth_token,
'token_secret' => $token->oauth_token_secret
)
);
} else if (isset($_GET['code'])) {
$token = $this->FacebookHelper->facebook->getAccessToken();
$userinfo = $this->FacebookHelper->getUserInfo();
$networkData = array(
'FacebookData' => array(
'username' => $userinfo['username'],
'name' => $userinfo['name'],
'email' => $userinfo['email'],
'token' => $token,
'link' => $userinfo['link'],
)
);
}
$this->Session->write('NetworkData', $networkData);
if($page == 'settings') {
$this->redirect(array('controller' => 'fonykers', 'action' => 'settings/networks'));
}
}
这是检索网络数据中的内容并将其设置到会话的函数:
function settings($tab) {
$this->layout = 'frontend';
$this->Fonyker->recursive = -1;
$this->TwitterData->recursive = -1;
$this->FacebookData->recursive = -1;
if(!$this->checkSessionCookie()) {
$this->redirect(array('controller' => 'pages', 'action' => 'home'));
}
$fields = array(
'Fonyker.id',
'Fonyker.username',
'Fonyker.name',
'Fonyker.email',
'Fonyker.gender',
'Fonyker.birthdate',
'Fonyker.image_url'
);
$fonyker = $this->Fonyker->find('first', array(
'conditions' => array(
'Fonyker.fonykid' => $this->Session->read('Fonyker.Fonyker.fonykid')
),
'fields' => $fields
));
$this->Fonyker->set($fonyker);
$this->data = $fonyker;
if($this->Session->read('NetworkData')) {
$networkData = $this->Session->read('NetworkData');
$this->Session->delete('NetworkData');
if($networkData['TwitterData']) {
$networkData['TwitterData']['fonyker_id'] = $fonyker['Fonyker']['id'];
if($this->TwitterData->save($networkData)) {
$this->Session->write('TwitterData', $networkData['TwitterData']);
}
} else if($networkData['FacebookData']) {
$networkData['FacebookData']['fonyker_id'] = $fonyker['Fonyker']['id'];
if($this->FacebookData->save($networkData)) {
$this->Session->write('FacebookData', $networkData['FacebookData']);
}
}
}
pr($this->Session->read());
if(!$this->Session->read('TwitterData')) {
$this->TwitterHelper->setTwitterObj();
$this->set('twitterUrl', $this->TwitterHelper->twitterObj->getAuthorizeUrl(null, array('oauth_callback' => 'http://127.0.0.1/fonykweb/pages/retrieve_network/settings')));
} else {
$this->set('twitterUrl', '#');
}
if(!$this->Session->read('FacebookData')) {
$this->set('facebookUrl', $this->FacebookHelper->facebook->getLoginUrl(array('redirect_uri' => 'http://localhost/fonykweb/pages/retrieve_network/settings','scope' => 'email,user_birthday,publish_stream,offline_access')));
} else {
$this->set('facebookUrl', '#');
}
$this->set('tab', $tab);
}
这是如果用户退出网络,则删除网络的函数愿望:
function remove_network($network) {
$this->autoRender = false;
$this->Fonyker->recursive = -1;
$this->TwitterData->recursive = -1;
$this->FacebookData->recursive = -1;
$response = null;
if($network == 'twitter') {
$twitterData = $this->TwitterData->find('first', array(
'conditions' => array(
'TwitterData.fonyker_id' => $this->Session->read('TwitterData.fonyker_id')
)
));
if($this->TwitterData->delete($twitterData['TwitterData']['id'], false)) {
$this->TwitterHelper->setTwitterObj();
$twitterUrl = $this->TwitterHelper->twitterObj->getAuthorizeUrl(null, array('oauth_callback' => 'http://127.0.0.1/fonykweb/pages/retrieve_network/settings'));
$this->Session->delete('TwitterData');
$response = json_encode(array('ok' => true, 'url' => $twitterUrl));
} else {
$response = json_encode(array('ok' => false));
}
}
if($network == 'facebook') {
$facebookData = $this->FacebookData->find('first', array(
'conditions' => array(
'FacebookData.fonyker_id' => $this->Session->read('FacebookData.fonyker_id')
)
));
if($this->FacebookData->delete($facebookData['FacebookData']['id'], false)) {
$facebookUrl = $this->FacebookHelper->facebook->getLoginUrl(array('redirect_uri' => 'http://localhost/fonykweb/pages/retrieve_network/settings','scope' => 'email,user_birthday,publish_stream,offline_access'));
$this->Session->delete('FacebookData');
$response = json_encode(array('ok' => true, 'url' => $facebookUrl));
} else {
$response = json_encode(array('ok' => false));
}
}
echo $response;
}
查看代码:
<script type="text/javascript">
$(document).ready(function() {
var splitUrl = window.location.href.split('/');
$('#' + splitUrl[splitUrl.length - 1] + '-tab').addClass('active-tab');
$('#' + splitUrl[splitUrl.length - 1] + '-tab').children().addClass('active-tab');
});
</script>
<div class="prepend-1 prepend-top span-23">
<div class="tabs span-22">
<ul>
<li id="account-tab">
<a href="<?php echo $html->url(array('controller' => 'fonykers', 'action' => 'settings'), true); ?>/account">
Account
</a>
</li>
<li id="password-tab">
<a href="<?php echo $html->url(array('controller' => 'fonykers', 'action' => 'settings'), true); ?>/password">
Password
</a>
</li>
<li id="notifications-tab">
<a href="<?php echo $html->url(array('controller' => 'fonykers', 'action' => 'settings'), true); ?>/notifications">
Notifications
</a>
</li>
<li id="networks-tab">
<a href="<?php echo $html->url(array('controller' => 'fonykers', 'action' => 'settings'), true); ?>/networks">
Social Networks
</a>
</li>
</ul>
</div>
<div class="tab-content prepend-top prepend-1">
<?php
if($tab == 'account') {
echo $this->element('settings/account');
} else if ($tab == 'password') {
echo $this->element('settings/password');
} else if ($tab == 'notifications') {
echo $this->element('settings/notifications');
} else {
echo $this->element('settings/networks');
}
?>
</div>
</div>
元素代码:
<script type="text/javascript">
$(document).ready(function(){
var deleteNetwork = function(network, button) {
$.ajax({
url: '<?php echo $html->url('/fonykers/remove_network/', true); ?>' + network,
dataType: 'json',
type: 'POST',
success: function(response) {
if(response.ok) {
button.replaceWith('<a id="'+network+'-connect" class="connect-button connect" href="'+response.url+'" class="span-3">Connect</a>');
}
}
});
}
if($('#twitter-connect').attr('href') == '#'){
$('#twitter-connect').addClass('connected');
$('#twitter-connect').html('Connected');
} else {
$('#twitter-connect').addClass('connect');
$('#twitter-connect').html('Connect');
}
if($('#facebook-connect').attr('href') == '#'){
$('#facebook-connect').addClass('connected');
$('#facebook-connect').html('Connected');
} else {
$('#facebook-connect').addClass('connect');
$('#facebook-connect').html('Connect');
}
$('.connected').hover(
function() {
$(this).removeClass('connected');
$(this).addClass('disconnect');
$(this).html('Disconnect')
},
function() {
$(this).removeClass('disconnect');
$(this).addClass('connected');
$(this).html('Connected')
}
);
$('#twitter-connect').click(function(event) {
if($(this).attr('href') == '#') {
event.preventDefault();
deleteNetwork('twitter', $(this));
}
});
$('#facebook-connect').click(function(event) {
if($(this).attr('href') == '#') {
event.preventDefault();
deleteNetwork('facebook', $(this));
}
});
});
</script>
<div class="span-4 prepend-top">
<div class="span-4">
<div class="span-1">
<?php echo $html->image('twitter-connect.png', array('alt' => 'Twitter', 'class' => 'span-1', 'style' => 'height:40px;width:40px')); ?>
</div>
<div class="span-3 last">
<a id="twitter-connect" class="connect-button" href="<?php echo $twitterUrl; ?>" class="span-3"></a>
</div>
</div>
<div class="span-4 prepend-top">
<div class="span-1">
<?php echo $html->image('facebook-connect.png', array('alt' => 'Twitter', 'class' => 'span-1', 'style' => 'height:40px;width:40px')); ?>
</div>
<div class="span-3 last">
<a id="facebook-connect" class="connect-button" href="<?php echo $facebookUrl; ?>"></a>
</div>
</div>
</div>
抱歉,帖子很长。
I'm using session variables in CakePHP to store my relevant user Twitter and Facebook data, when the user logs in if he has linked his Twitter and FB accounts this information is saved in the session variable next to my own user data.
I have a screen where the user can link and unlink said social network data, the problem is the following:
Let's say I have both networks connected, I decide to disconnect from Facebook, the session variable for Facebook is deleted. Now I wish to reconnect to Facebook, I click on the Connect button, the Facebook data is saved but for some reason it deletes the Twitter variable.
The way my process works is the following:
1) User clicks on connect button.
2) User is directed to social network auth.
3) User is directed to a function that takes the required data, saves it in a session variable called NetworkData and is directed back to the page where he clicked the button.
4) The NetworkData is extracted, set as the according social network (Facebook or Twitter) in the session and is deleted from the session.
Code is as follows:
This is the function that the user is directed after login in to Twitter or FB:
function retrieve_network($page) {
$networkData = null;
$this->autoRender = false;
$this->layout = 'ajax';
if(isset($_GET['oauth_token'])) {
$token = $this->TwitterHelper->setOAuthToken($_GET['oauth_token']);
$userinfo = $this->TwitterHelper->getTwitterUserInfo();
$networkData = array(
'TwitterData' => array(
'username' => $userinfo['username'],
'name' => $userinfo['name'],
'token' => $token->oauth_token,
'token_secret' => $token->oauth_token_secret
)
);
} else if (isset($_GET['code'])) {
$token = $this->FacebookHelper->facebook->getAccessToken();
$userinfo = $this->FacebookHelper->getUserInfo();
$networkData = array(
'FacebookData' => array(
'username' => $userinfo['username'],
'name' => $userinfo['name'],
'email' => $userinfo['email'],
'token' => $token,
'link' => $userinfo['link'],
)
);
}
$this->Session->write('NetworkData', $networkData);
if($page == 'settings') {
$this->redirect(array('controller' => 'fonykers', 'action' => 'settings/networks'));
}
}
This is the function that retrieves what's in network data and sets it to the session:
function settings($tab) {
$this->layout = 'frontend';
$this->Fonyker->recursive = -1;
$this->TwitterData->recursive = -1;
$this->FacebookData->recursive = -1;
if(!$this->checkSessionCookie()) {
$this->redirect(array('controller' => 'pages', 'action' => 'home'));
}
$fields = array(
'Fonyker.id',
'Fonyker.username',
'Fonyker.name',
'Fonyker.email',
'Fonyker.gender',
'Fonyker.birthdate',
'Fonyker.image_url'
);
$fonyker = $this->Fonyker->find('first', array(
'conditions' => array(
'Fonyker.fonykid' => $this->Session->read('Fonyker.Fonyker.fonykid')
),
'fields' => $fields
));
$this->Fonyker->set($fonyker);
$this->data = $fonyker;
if($this->Session->read('NetworkData')) {
$networkData = $this->Session->read('NetworkData');
$this->Session->delete('NetworkData');
if($networkData['TwitterData']) {
$networkData['TwitterData']['fonyker_id'] = $fonyker['Fonyker']['id'];
if($this->TwitterData->save($networkData)) {
$this->Session->write('TwitterData', $networkData['TwitterData']);
}
} else if($networkData['FacebookData']) {
$networkData['FacebookData']['fonyker_id'] = $fonyker['Fonyker']['id'];
if($this->FacebookData->save($networkData)) {
$this->Session->write('FacebookData', $networkData['FacebookData']);
}
}
}
pr($this->Session->read());
if(!$this->Session->read('TwitterData')) {
$this->TwitterHelper->setTwitterObj();
$this->set('twitterUrl', $this->TwitterHelper->twitterObj->getAuthorizeUrl(null, array('oauth_callback' => 'http://127.0.0.1/fonykweb/pages/retrieve_network/settings')));
} else {
$this->set('twitterUrl', '#');
}
if(!$this->Session->read('FacebookData')) {
$this->set('facebookUrl', $this->FacebookHelper->facebook->getLoginUrl(array('redirect_uri' => 'http://localhost/fonykweb/pages/retrieve_network/settings','scope' => 'email,user_birthday,publish_stream,offline_access')));
} else {
$this->set('facebookUrl', '#');
}
$this->set('tab', $tab);
}
This is the function that removes the network if the user wishes:
function remove_network($network) {
$this->autoRender = false;
$this->Fonyker->recursive = -1;
$this->TwitterData->recursive = -1;
$this->FacebookData->recursive = -1;
$response = null;
if($network == 'twitter') {
$twitterData = $this->TwitterData->find('first', array(
'conditions' => array(
'TwitterData.fonyker_id' => $this->Session->read('TwitterData.fonyker_id')
)
));
if($this->TwitterData->delete($twitterData['TwitterData']['id'], false)) {
$this->TwitterHelper->setTwitterObj();
$twitterUrl = $this->TwitterHelper->twitterObj->getAuthorizeUrl(null, array('oauth_callback' => 'http://127.0.0.1/fonykweb/pages/retrieve_network/settings'));
$this->Session->delete('TwitterData');
$response = json_encode(array('ok' => true, 'url' => $twitterUrl));
} else {
$response = json_encode(array('ok' => false));
}
}
if($network == 'facebook') {
$facebookData = $this->FacebookData->find('first', array(
'conditions' => array(
'FacebookData.fonyker_id' => $this->Session->read('FacebookData.fonyker_id')
)
));
if($this->FacebookData->delete($facebookData['FacebookData']['id'], false)) {
$facebookUrl = $this->FacebookHelper->facebook->getLoginUrl(array('redirect_uri' => 'http://localhost/fonykweb/pages/retrieve_network/settings','scope' => 'email,user_birthday,publish_stream,offline_access'));
$this->Session->delete('FacebookData');
$response = json_encode(array('ok' => true, 'url' => $facebookUrl));
} else {
$response = json_encode(array('ok' => false));
}
}
echo $response;
}
View code:
<script type="text/javascript">
$(document).ready(function() {
var splitUrl = window.location.href.split('/');
$('#' + splitUrl[splitUrl.length - 1] + '-tab').addClass('active-tab');
$('#' + splitUrl[splitUrl.length - 1] + '-tab').children().addClass('active-tab');
});
</script>
<div class="prepend-1 prepend-top span-23">
<div class="tabs span-22">
<ul>
<li id="account-tab">
<a href="<?php echo $html->url(array('controller' => 'fonykers', 'action' => 'settings'), true); ?>/account">
Account
</a>
</li>
<li id="password-tab">
<a href="<?php echo $html->url(array('controller' => 'fonykers', 'action' => 'settings'), true); ?>/password">
Password
</a>
</li>
<li id="notifications-tab">
<a href="<?php echo $html->url(array('controller' => 'fonykers', 'action' => 'settings'), true); ?>/notifications">
Notifications
</a>
</li>
<li id="networks-tab">
<a href="<?php echo $html->url(array('controller' => 'fonykers', 'action' => 'settings'), true); ?>/networks">
Social Networks
</a>
</li>
</ul>
</div>
<div class="tab-content prepend-top prepend-1">
<?php
if($tab == 'account') {
echo $this->element('settings/account');
} else if ($tab == 'password') {
echo $this->element('settings/password');
} else if ($tab == 'notifications') {
echo $this->element('settings/notifications');
} else {
echo $this->element('settings/networks');
}
?>
</div>
</div>
Element code:
<script type="text/javascript">
$(document).ready(function(){
var deleteNetwork = function(network, button) {
$.ajax({
url: '<?php echo $html->url('/fonykers/remove_network/', true); ?>' + network,
dataType: 'json',
type: 'POST',
success: function(response) {
if(response.ok) {
button.replaceWith('<a id="'+network+'-connect" class="connect-button connect" href="'+response.url+'" class="span-3">Connect</a>');
}
}
});
}
if($('#twitter-connect').attr('href') == '#'){
$('#twitter-connect').addClass('connected');
$('#twitter-connect').html('Connected');
} else {
$('#twitter-connect').addClass('connect');
$('#twitter-connect').html('Connect');
}
if($('#facebook-connect').attr('href') == '#'){
$('#facebook-connect').addClass('connected');
$('#facebook-connect').html('Connected');
} else {
$('#facebook-connect').addClass('connect');
$('#facebook-connect').html('Connect');
}
$('.connected').hover(
function() {
$(this).removeClass('connected');
$(this).addClass('disconnect');
$(this).html('Disconnect')
},
function() {
$(this).removeClass('disconnect');
$(this).addClass('connected');
$(this).html('Connected')
}
);
$('#twitter-connect').click(function(event) {
if($(this).attr('href') == '#') {
event.preventDefault();
deleteNetwork('twitter', $(this));
}
});
$('#facebook-connect').click(function(event) {
if($(this).attr('href') == '#') {
event.preventDefault();
deleteNetwork('facebook', $(this));
}
});
});
</script>
<div class="span-4 prepend-top">
<div class="span-4">
<div class="span-1">
<?php echo $html->image('twitter-connect.png', array('alt' => 'Twitter', 'class' => 'span-1', 'style' => 'height:40px;width:40px')); ?>
</div>
<div class="span-3 last">
<a id="twitter-connect" class="connect-button" href="<?php echo $twitterUrl; ?>" class="span-3"></a>
</div>
</div>
<div class="span-4 prepend-top">
<div class="span-1">
<?php echo $html->image('facebook-connect.png', array('alt' => 'Twitter', 'class' => 'span-1', 'style' => 'height:40px;width:40px')); ?>
</div>
<div class="span-3 last">
<a id="facebook-connect" class="connect-button" href="<?php echo $facebookUrl; ?>"></a>
</div>
</div>
</div>
Sorry for the long post.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
在您的retrieve_network操作中,我假设您在用户重新连接到特定服务时调用该操作,您将覆盖NetworkData会话变量
如果您发现 1 个特定服务已连接到:
或者
您将 $networkData 设置为返回的服务对象,然后通过以下方式覆盖整个会话:
按照您的代码,我将始终检查现有服务当前是否处于会话中,如果是的话不要覆盖整个会话,只需将特定数据添加到现有的 NetworkData 会话数组中:
注意:这只是一个示例,展示如何实现此目的。对于这种特殊情况,我会用更好的逻辑重构该方法,也许将 TwitterData 和 FacebookData 存储在它们自己的单独数组中,而不是更大更复杂的 NetworkData 数组。此外,您可以通过 $this->params['url']['paramname'] 访问 $_GET 参数以维护 cakePHP 约定。
In your retrieve_network action, which I am assuming you call when a user reconnects to a particular service, you are overwriting the NetworkData session variable
if you find 1 particular Service has been connected to:
OR
You set $networkData to the returned services object and then overwrite the whole session via:
Following your code, I would always check to see if an existing service is currently in session and if so do not overwrite the whole session, just add the particular data to the existing NetworkData session array:
Note: This is just an example showing how you can achieve this. I would refactor that method with better logic for this particular situation, perhaps storing TwitterData and FacebookData in their own separate arrays as opposed to a larger more complex NetworkData array. Additionally, you can access $_GET params via $this->params['url']['paramname'] to maintain cakePHP convention.
我认为问题在于您正在替换网络数据,而不是合并它。
这意味着,例如,当您使用 FB 登录时,您可以用 FB 替换任何 twitter 数据,而不是同时保留它们。
我希望也许不是
那样
可行。
否则,在我看来,会话删除代码不应该与一个人交互来删除另一个人。不过,我可能会在浏览时错过一些东西。我会做一些 echo()ing/调试来跟踪代码执行路径。
I think the issue is that you are replacing network data, instead of merging it.
This means that when you login with FB for example, you replace any twitter data with FB, instead of keeping them both.
I'm hoping that maybe instead of
that
might work.
Otherwise, it seems to me the session deleting code shouldn't be interacting for one to delete the other. I could have missed something in skimming it though. I'd do some echo()ing / debugging to follow the code execution paths.