Kenji
kenji****@club*****
2008年 1月 11日 (金) 21:14:13 JST
Kenji です。 結構、かっこいい実装ですねぇ。 On Fri, 11 Jan 2008 19:54:29 +0900 "Kenichi Ando" <neo.k****@gmail*****> wrote: > bossatamaです。 > > sessionクラスを継承する方法で、以下を実装してみました。 > > 携帯で実際に動くカウンタです。 > http://codeigniter.jp/mobile/session/ > > URIは次のようになります: > http://codeigniter.jp/mobile/session/SESSID=**************** = を含める必要性はなさそうです。 > libraries/My_Session.php > <?php if (!defined('BASEPATH')) exit('No direct script access allowed'); > > class MY_Session extends CI_Session { > > var $couldnt_read_cookie = FALSE; > > function MY_Session() > { > parent::CI_Session(); > } > > /** > * Fetch the current session data if it exists > * > * @access public > * @return void > */ > function sess_read() > { > // Fetch the cookie > $session = $this->CI->input->cookie($this->sess_cookie); > > if ($session === FALSE) > { > //Remember that I couldn't read the cookie > $this->couldnt_read_cookie = TRUE; > > //Attempt to load sess_id from url > $url_session = array(); > preg_match ( "|SESSID=[^/\\\\]*|", $this->CI->uri->segment ( > $this->CI->uri->total_segments() ), $url_session ); > > if (empty ( $url_session )) > { > log_message('debug', 'A session cookie was not found.'); > return FALSE; > > } > else > { > log_message('debug', 'No session cookie found but retrieved id from url.'); > > $sessid = str_replace ( "SESSID=", "", $url_session[0] ); > > if ($this->use_database === TRUE) > { > $this->CI->db->select ( "userdata" ); > $this->CI->db->from ( $this->session_table ); > $this->CI->db->where ( 'session_id', $sessid ); > $q = $this->CI->db->get(); > if ($q->num_rows() > 0) > { > $r = $q->row(); > $session = $r->userdata; > } > else > { > log_message('debug', "SESSID doesn't match. Possible hacking attempt"); > return FALSE; > } > > } > else > { > //Create some dummy session data which will be considered as a > hacking attempt > //Unfortunately this solution relies on DB sessions > $session["session_id"] = $sessid; > $session = serialize ($session); > } > } > } > // Decrypt and unserialize the data > if ($this->encryption == TRUE) > { > $session = $this->CI->encrypt->decode($session); > } > $session = @unserialize($this->strip_slashes($session)); > > if (!is_array($session) OR !isset($session['last_activity'])) > { > log_message('error', 'The session cookie data did not contain a > valid array. This could be a possible hacking attempt.'); > return FALSE; > } > > // Is the session current? > if (($session['last_activity'] + $this->sess_length) < $this->now) > { > $this->sess_destroy(); > return FALSE; > } > > // Does the IP Match? 携帯電話ではIPアドレスがころころ変わるのでNG この IPアドレスマッチは、設定項目ですし、デフォルトFALSE ですので、 あえて、コメントアウトする必要はないように思います。 あるいは is_mobile だったら、チェックしないとか。 > /* > if ($this->CI->config->item('sess_match_ip') == TRUE AND > $session['ip_address'] != $this->CI->input->ip_address()) > { > $this->sess_destroy(); > return FALSE; > } > */ > // Does the User Agent Match? > if ($this->CI->config->item('sess_match_useragent') == TRUE AND > $session['user_agent'] != substr($this->CI->input->user_agent(), 0, > 50)) > { > $this->sess_destroy(); > return FALSE; > } > > // Is there a corresponding session in the DB? > if ($this->use_database === TRUE) > { > $this->CI->db->where('session_id', $session['session_id']); > > /*携帯電話ではIPアドレスがころころ変わるのでNG > > if ($this->CI->config->item('sess_match_ip') == TRUE) > { > $this->CI->db->where('ip_address', $session['ip_address']); > } > */ > if ($this->CI->config->item('sess_match_useragent') == TRUE) > { > $this->CI->db->where('user_agent', $session['user_agent']); > } > > $query = $this->CI->db->get($this->session_table); > > if ($query->num_rows() == 0) > { > $this->sess_destroy(); > return FALSE; > } > else > { > $row = $query->row(); > if (($row->last_activity + $this->sess_length) < $this->now) > { > $this->CI->db->where('session_id', $session['session_id']); > $this->CI->db->delete($this->session_table); > $this->sess_destroy(); > return FALSE; > } > } > } > // Session is valid! > $this->userdata = $session; > unset($session); > return TRUE; > } > > /** > * Write the session cookie > * > * @access public > * @return void > */ > function sess_write() > { > parent::sess_write(); > > //If I couldn't read the cookie last time, attach session data to > //url in case I can't read the cookie in future attempts > //This functionality demands that URLs are created using CI > //tools such as URL helper or reminding to always attach the url > //suffix (even if you don't define one > if ( $this->couldnt_read_cookie ) > { > //Unset in case we rewrite the session > $this->couldn_read_cookie = FALSE; > > $this->CI->config->set_item ( 'url_suffix','/SESSID=' . > $this->userdata ( 'session_id' ) . config_item ( 'url_suffix' ) ); > } > > //Save userdata in database > if ($this->use_database === TRUE) > { > $set = array ( > "session_id" => $this->userdata ( 'session_id' ), > "ip_address" => $this->userdata ( 'ip_address' ), > "user_agent" => $this->userdata ( 'user_agent' ), > "last_activity" => $this->userdata ( 'last_activity' ), > "userdata" => serialize ( $this->userdata ) > ); > $this->CI->db->where ( "session_id", $this->userdata ( 'session_id' ) ); > $this->CI->db->update ( $this->session_table, $set ); > } > } > > } > ?> > > このセッションはDB必須です。 > CREATE TABLE `ci_sessions` ( > `session_id` varchar(40) NOT NULL default '0', > `ip_address` varchar(16) NOT NULL default '0', > `user_agent` varchar(50) NOT NULL default '', > `last_activity` int(10) unsigned NOT NULL default '0', > `userdata` text NOT NULL, > PRIMARY KEY (`session_id`) > ) ENGINE=MyISAM DEFAULT CHARSET=utf8; > > config/config.phpでDBに変更する > $config['sess_use_database'] = TRUE; > > URIセグメントパターンに「=」を追加します。 > $config['permitted_uri_chars'] = '= a-z 0-9~%.:_-'; > > config/routes.phpでルーティングを変更させます。 > $route ['(.*)SESSID=.*$'] = "$1"; > 携帯なんで、Shift_JISでもいけるように英文に修正 > controllers/session.php > <?php > class Session extends Controller { > > function Session() > { > parent::Controller(); > $this->load->library('session'); > $this->load->helper('url'); > } > > function index() > { > if (!$this->session->userdata('conut')) > { > $this->session->set_userdata('conut', 1); > } > else > { > $count = $this->session->userdata('conut'); > $count++; > $this->session->set_userdata('conut', $count); > } > echo 'SESSIONID:' . $this->session->userdata('session_id') . '<br>'; > echo 'COUNTER:' . $this->session->userdata('conut') . '<br>'; > echo anchor('/session', 'RELOAD'); > } > } > ?> > > SESSIDが自動的に付加されます。 > > _______________________________________________ > Codeigniter-users mailing list > Codei****@lists***** > http://lists.sourceforge.jp/mailman/listinfo/codeigniter-users