[Codeigniter-users] モバイルサイトのセッションについて

Back to archive index

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




Codeigniter-users メーリングリストの案内
Back to archive index