2012-09-04 56 views
0

這裏是我的驗證邏輯:CGI ::會議記錄隨機用戶輸出

sub user_logon { 
my ($dbh, $cgi, $cache, $logout) = @_; 

#use Log::Log4perl qw(:easy); 
#Log::Log4perl->easy_init($DEBUG); 

my $session = new CGI::Session("driver:MySQL", $cgi, {Handle=>$dbh}); 

$session->expires("+3h"); 
my $auth = new CGI::Session::Auth::DBI({ 
    CGI    => $cgi, 
    Session   => $session, 
    IPAuth   => 1, 
    DBHandle  => $dbh, 
    #Log    => 1, 
}); 

if($logout) { 
    $auth->logout(); 
} 
else { 
    $auth->authenticate(); 

    if($auth->loggedIn) { 
     my $user = Cherry::Schema::ResultSet::Employee::get_employee($dbh, $cache, { number => $auth->{userid} }); 

     if (!$user->{active}) { 
      return { error => $user->{name} . ' is not an active employee.' }; 
     } 

     $user->{cookie} = $auth->sessionCookie(); 
     return $user; 
    } 
    elsif($cgi->param('action') eq 'logon') { 
     if($cgi->param('log_username') && $cgi->param('log_username')) { 
      return { error => 'Your username and/or password did not match.' }; 
     } 
     elsif(!$cgi->param('log_username') || !$cgi->param('log_username')) { 
      return { error => 'Please enter a username and a password.' }; 
     } 
    } 
    else { 
     return { error => 'You are not logged in' }; 
    } 
} 
} 

sub handle_authentication { 
my ($dbh, $cache, $config, $params, $cgi) = @_; 

if(($cgi->param('auth') || '') eq 'super_user') { # for automation 
    return; 
} 

if(($params->{action} || '') eq 'log_off') { 
    user_logon($dbh, $cgi, $cache, 1); # 1 means log out 
    login_form($config, 'Successfully logged out', $params->{login_url}, $params->{title}); 
} 

my $user = user_logon($dbh, $cgi, $cache); 

if(exists $user->{error}) { 
    login_form($config, $user->{error}, $params->{login_url}, $params->{title}); 
} 
elsif($user->{number}) { 
    return $user; 
} 

} 
在我的代碼

然後,我每次打印頭時,它看起來是這樣的:

my $user = Cherry::Authentication::handle_authentication(
$dbh, 
$cache, 
\%config, 
{ 
    action  => $FORM{action}, 
    username => $FORM{log_username}, 
    password => $FORM{log_password}, 
    auth  => $FORM{auth} 
}, 
$cgi 
); 
print header( 
    -type => 'application/json', 
    -cookie => $user->{cookie} 
); 

的問題在於,這段代碼似乎在80%的時間內工作得很好。另外20%的用戶正在被踢出(而不是在陳舊3小時之後)。

是否有這個代碼的任何明顯的缺陷?我有沒有留下任何關鍵代碼?

如果你覺得有沒有足夠的信息在這裏給一個可行的解決方案,你有什麼可以做,以解決這類問題的任何一般性建議?

+1

你可以看看用戶發送標題?也許cookie會消失。另外,是否有多個數據庫服務器?我已經看到了這個與Web服務器集羣,其中會話文件進入本地文件系統,而不是共享一個,但你沒有文件,你有一個分貝。可能有類似的事情發生。這是發生在所有用戶還是一些?他們的特點是什麼?你能找到共同的標識符來分組嗎?我首先看看文件/會話。密切關注桌面,尋找同一用戶何時進行第二次會話。 – simbabque

+0

我同意simbabque說的。隨着目前的信息,我會說增加更多的日誌。如果註銷功能被觸發,您應該記錄,何時和由誰等。 –

回答

0

有了這個特殊問題,在玩一些代碼,我不知道的。

$cookie = CGI::Cookie->new(
    -name  => $session->name, # problem line 
    -value  => $session->id, # problem line 
    -expires => '+1y', 
    -path  => '/', 
    -secure  => 0, 
); 

my @header = (
    -cookie => $cookie, 
    -type => 'text/html', 
    -status  => $status 
); 

print $cgi->header(@header); 

與評論#problem線是當一個已經存在,甚至分配一個新的會話的線。

我似乎有問題大多數用戶的計算機上安裝Fiddler HTTP Debugger。然後,一旦用戶意外退出,我查看了日誌。我能夠找到訪問一個網址的用戶與下一個請求的意外登出之間的關聯。