問題現象:
退出提示 「Access denied for agent changed」

排查思路:
這是與 uc 請求的時候出問題導致。具體報錯部分是 uc_server/mode/user.php 中的 function init_input 函式部分的 ,對 $agent 進行了判斷。

  1. if(($getagent
    && $getagent != $this->input['agent']) || (!$getagent
    && md5($_SERVER['HTTP_USER_AGENT']) != $agent)) {
  2.                                 exit('Access denied for agent changed');
  3.                         }


面我們來簡單分析下退出的時候是怎麼 uc 請求的,開啟 class_member.php 找到 on_logout 函式部分
$ucsynlogout = $this->setting['allowsynlogin'] ? uc_user_synlogout() :
''; 這這麼一行程式碼,這是判斷程式是否開啟了同步登入。如果開啟了同步登入  uc_user_synlogout() 會執行請求
接下來,分析下 uc_user_synlogout( 這些函式的呼叫是來自 loaducenter()) 。開啟 uc_client/client.php

  1. function uc_user_synlogout() {
  2.         if(@include UC_ROOT.'./data/cache/apps.php') {
  3.                 if(count($_CACHE['apps']) > 1) {
  4.                         $return = uc_api_post('user', 'synlogout', array());
  5.                 } else {
  6.                         $return = '';
  7.                 }
  8.         }
  9.         return $return;
  10. }

使用 post 方式請求 uc 。 大家可以閱讀下 uc_api_post   是怎麼處理的 。 uc_api_post 中有 uc_api_requestdata 這麼個函式
再看下  uc_api_input 函式。這個函式就是對輸入內容進行處理 使用 uc_authcode 進行加密處理,其中的 UC_key
是咱們熟悉的 config_ucenter.php 中的 UC_KEY 。 到此,大家應該對請求部分大體上有個瞭解,下面我們來看
uc_server 端的接收

我們看到 uc_api_requestdata 函式中的部分

  1. $post = "m=$module&a=$action&inajax=2&release=".UC_CLIENT_RELEASE."&input=$input&appid=".UC_APPID.$extra;

然後使用 uc_fopen2(此函式原理,大家自行閱讀在此不做介紹) 去請求。

開啟 uc_server/index.php 檔案

  1. if(in_array($m,
    array('app', 'frame', 'user', 'pm', 'pm_client', 'tag', 'feed',
    'friend', 'domain', 'credit', 'mail', 'version'))) {
  2.         if(file_exists(UC_ROOT.RELEASE_ROOT."control/$m.php")) {
  3.                 include UC_ROOT.RELEASE_ROOT."control/$m.php";
  4.         } else {
  5.                 include UC_ROOT."control/$m.php";
  6.         }
  7.         $classname = $m.'control';
  8.         $control = new $classname();
  9.         $method = 'on'.$a;
  10.         if(method_exists($control, $method) && $a{0} != '_') {
  11.                 $data = $control->$method();
  12.                 echo is_array($data) ? $control->serialize($data, 1) : $data;
  13.                 exit;
  14.         } elseif(method_exists($control, '_call')) {
  15.                 $data = $control->_call('on'.$a, '');
  16.                 echo is_array($data) ? $control->serialize($data, 1) : $data;
  17.                 exit;
  18.         } else {
  19.                 exit('Action not found!');
  20.         }
  21. }


對用請求的內容進行處理,然後找到對應的模組就行響應請求。   退出的時候,程式會進入到 uc_server/model/base.php 檔案中的
init_input() 函式 $input = $this->authcode($input, 'DECODE',
$this->app['authkey']); 如果這裡的解壓有問題。那麼,就會導致出現 『Access denied for agent
changed』 這樣的錯誤。

解決方法:
現在我們來分析下原因:
在這個請求的過程中,牽涉的到加密和解密兩個部分,如果兩個其中有一方的 key 不一樣都會導致出現問題,使用者要仔細檢查
config_ucenter.php 中 UC_KEY 和 UC_APPID 是否與
uc_server/data/cache/apps.php 中的 authkey 和 appid(這裡 key 和 appid
有時候會出現與 ucenter 中心的不一樣問題,一般是檔案許可權導致) 是否對應。 其次,有時候
域名有 uc_api 中的 uc 訪問路徑有問題的時候,請配置下 config_ucenter.php 中的 UC_IP