1

私はCodeigniter 2.0 Web アプリを実行しており、DB オプションをオンにしてセッション ライブラリを使用しているため、Web サイトのすべての接続に対して、'ci_sessions'以下を格納するという名前の MySQL テーブルがあります。

  • Session_id
  • IPアドレス
  • ユーザーエージェント
  • 最後の活動
  • ユーザー_データ

そして、私には2つの問題があります:

  1. IP を使用した Google ボット66.249.72.152
  2. IPでクロン0.0.0.0

サーバーが cron を実行するたびに、または Google ボットがページをクロールするたびに、新しいセッションが作成されます。そのため、IP とは何百もの同じセッションがあり、IP0.0.0.0とは何百ものセッションがあります66.249.72.152

ボットまたは cron によるセッションの作成を停止する方法を知っている人はいますか? または、これができない場合...これらのセッションを時々自動的に削除する方法を知っている人はいますか? ありがとう!

4

4 に答える 4

1

コア ファイルを変更しないことをお勧めします。セッション クラスを拡張することをお勧めします。次に、./app/libraries/ に MY_Session.php ファイルを作成しのコードを貼り付けます。

<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
/**
 * ------------------------------------------------------------------------
 * CI Session Class Extension
 * ------------------------------------------------------------------------
 *
*/
class MY_Session extends CI_Session {
   /**
    * sess_update()
    * 
    * Do not create session if it's in the cli environment
    *
    * @access    public
    * @return    void
    */
    public function sess_create() 
    {
        $CI         = get_instance();
        $ip_address = $CI->input->ip_address();

        if ( ($ip_address != '0.0.0.0' && $CI->input->user_agent() != '0') || $ip_address != '66.249.72.152'){
            parent::sess_create();
        }
    }
}

/* End of file MY_Session.php */
/* Location: ./app/libraries/MY_Session.php */
?>

これは動作します

于 2013-03-01T23:28:54.107 に答える
1

考えられる解決策は、セッションを作成してはならない IP のブラックリストを実装することです。

これを行うための 2 つの方法を作成しました。

アプリケーション/設定/config.php

/*
|--------------------------------------------------------------------------
| Session Variables
|--------------------------------------------------------------------------
|
| 'sess_cookie_name'        = the name you want for the cookie
| 'sess_expiration'         = the number of SECONDS you want the session to last.
|   by default sessions last 7200 seconds (two hours).  Set to zero for no expiration.
| 'sess_expire_on_close'    = Whether to cause the session to expire automatically
|   when the browser window is closed
| 'sess_encrypt_cookie'     = Whether to encrypt the cookie
| 'sess_use_database'       = Whether to save the session data to a database
| 'sess_table_name'         = The name of the session database table
| 'sess_match_ip'           = Whether to match the user's IP address when reading the session data
| 'sess_match_useragent'    = Whether to match the User Agent when reading the session data
| 'sess_time_to_update'     = how many seconds between CI refreshing Session Information
| 'sess_ignore_ip'          = array of IP addresses to ignore
|
*/
$config['sess_cookie_name']     = 'ci_session';
$config['sess_expiration']      = 7200;
$config['sess_expire_on_close'] = FALSE;
$config['sess_encrypt_cookie']  = FALSE;
$config['sess_use_database']    = FALSE;
$config['sess_table_name']      = 'ci_sessions';
$config['sess_match_ip']        = FALSE;
$config['sess_match_useragent'] = TRUE;
$config['sess_time_to_update']  = 300;
$config['sess_ignore_ip']       = array('66.249.72.152', '0.0.0.0');

システム/ライブラリ/session.php

/**
 * Session Constructor
 *
 * The constructor runs the session routines automatically
 * whenever the class is instantiated.
 */
public function __construct($params = array())
{
    log_message('debug', "Session Class Initialized");

    // Set the super object to a local variable for use throughout the class
    $this->CI =& get_instance();

    // Set all the session preferences, which can either be set
    // manually via the $params array above or via the config file
    foreach (array('sess_encrypt_cookie', 'sess_use_database', 'sess_table_name', 'sess_expiration', 'sess_expire_on_close', 'sess_match_ip', 'sess_match_useragent', 'sess_cookie_name', 'cookie_path', 'cookie_domain', 'cookie_secure', 'sess_time_to_update', 'time_reference', 'cookie_prefix', 'encryption_key', 'sess_ignore_ip') as $key)
    {
        $this->$key = (isset($params[$key])) ? $params[$key] : $this->CI->config->item($key);
    }

    if ($this->encryption_key == '')
    {
        show_error('In order to use the Session class you are required to set an encryption key in your config file.');
    }

    // Load the string helper so we can use the strip_slashes() function
    $this->CI->load->helper('string');

    // Do we need encryption? If so, load the encryption class
    if ($this->sess_encrypt_cookie == TRUE)
    {
        $this->CI->load->library('encrypt');
    }

    // Are we using a database?  If so, load it
    if ($this->sess_use_database === TRUE AND $this->sess_table_name != '')
    {
        $this->CI->load->database();
    }

    // Set the "now" time.  Can either be GMT or server time, based on the
    // config prefs.  We use this to set the "last activity" time
    $this->now = $this->_get_time();

    // Set the session length. If the session expiration is
    // set to zero we'll set the expiration two years from now.
    if ($this->sess_expiration == 0)
    {
        $this->sess_expiration = (60*60*24*365*2);
    }

    // Set the cookie name
    $this->sess_cookie_name = $this->cookie_prefix.$this->sess_cookie_name;

    $ip_address = $this->CI->input->ip_address();
    if(!isset($this->sess_ignore_ip) || empty($this->sess_ignore_ip) || !in_array($ip_address, $this->sess_ignore_ip))
    {
        // Run the Session routine. If a session doesn't exist we'll
        // create a new one.  If it does, we'll update it.
        if ( ! $this->sess_read())
        {
            $this->sess_create();
        }
        else
        {
            $this->sess_update();
        }
    }

    // Delete 'old' flashdata (from last request)
    $this->_flashdata_sweep();

    // Mark all new flashdata as old (data will be deleted before next request)
    $this->_flashdata_mark();

    // Delete expired sessions if necessary
    $this->_sess_gc();

    log_message('debug', "Session routines successfully run");
}

/**
 * Garbage collection
 *
 * This deletes expired session rows from database
 * if the probability percentage is met
 *
 * @access  public
 * @return  void
 */
function _sess_gc()
{
    if ($this->sess_use_database != TRUE)
    {
        return;
    }

    srand(time());
    if ((rand() % 100) < $this->gc_probability)
    {
        $expire = $this->now - $this->sess_expiration;

        $this->CI->db->where("last_activity < {$expire}");
        if(isset($this->sess_ignore_ip) && !empty($this->sess_ignore_ip))
            $this->db->where_in('ip_address', $this->sess_ignore_ip);
        $this->CI->db->delete($this->sess_table_name);

        log_message('debug', 'Session garbage collection performed.');
    }
}

構成ファイルには、無視する IP アドレスの配列が含まれています。

セッション ライブラリでは、コンストラクターを更新して、現在の IP アドレスが上記の構成設定に存在するかどうかを確認し、存在する場合は、セッションを作成または更新するコードをスキップするようにしました。

これに加えて、構成内_sess_gcの IP と一致する IP を持つすべてのセッション行を削除する新しい where_in ステートメントを追加しました。コンストラクター メソッドを実装する場合、この部分は実際には必要ありません。

于 2012-06-13T13:31:47.170 に答える
-3

ci_sessions テーブルを変更し、UNIQUE 制約を ip_address フィールドに追加します。そうすれば、セッションが重複することはありません..

より複雑なアプローチは、挿入時にトリガーを使用することです。これにより、IPアドレスが上記の2つのアドレスに含まれているかどうかが確認されます. はいの場合は、データベースに挿入しないでください..

于 2012-06-13T13:19:44.010 に答える