0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

codeigniter UTF8対応とモバイルセッション対応

Last updated at Posted at 2018-05-31

UTF-8対応

<?php

class MY_Utf8 extends CI_Utf8 {

	function __construct(){
		parent::__construct();
	}

	/**
	 * Clean UTF-8 strings
	 *
	 * Ensures strings are UTF-8
	 *
	 * mobile対応で、SJIS-win => utf-8 に変換するため、サニタイズ前に変換する必要がある
	 * とくにauは、htmlのaccept-charsetでは、utf-8には変換されないため対応が必須
	 *
	 * @access	public
	 * @param	string
	 * @return	string
	 */
	function clean_string($str)
	{
		if ($this->_is_ascii($str) === FALSE)
		{
			if (mb_detect_encoding($str) != 'UTF-8') $str = mb_convert_encoding($str, "UTF-8", "auto");
			$str = @iconv('UTF-8', 'UTF-8//IGNORE', $str);
		}

		return $str;
	}
}

モバイルsession対応

  1. テーブルの追加
  2. configの変更
  3. routes.phpに追記
config.php
$config['sess_cookie_name']		= 'gk_session';
$config['sess_expiration']		= 7200;
$config['sess_expire_on_close']	= FALSE;
$config['sess_encrypt_cookie']	= TRUE;
$config['sess_use_database']	= TRUE;
$config['sess_table_name']		= 'ci_sessions';
$config['sess_match_ip']		= FALSE;
$config['sess_match_useragent']	= TRUE;
$config['sess_time_to_update']	= 300;

$config['permitted_uri_chars'] = '= a-z 0-9~%.:_-';

$config['csrf_protection'] = FALSE;

routes.php

$route['(.*)SESSID=.*$']     = "$1";

※session_idは、セッションハイジャック対策のため毎回更新される。


<?php if (!defined('BASEPATH')) exit('No direct script access allowed');
/**
 * this MY_Session subclass is database assosiation.
 * execute before 'ci_sessions' table createing.
 *
 * CREATE TABLE IF NOT EXISTS `ci_sessions` (
 * 	session_id varchar(40) DEFAULT '0' NOT NULL,
 * 	ip_address varchar(16) DEFAULT '0' NOT NULL,
 * 	user_agent varchar(120) NOT NULL,
 * 	last_activity int(10) unsigned DEFAULT 0 NOT NULL,
 * 	user_data text NOT NULL,
 * 	PRIMARY KEY (session_id),
 * 	KEY `last_activity_idx` (`last_activity`)
 * );
 *
 * this MY_session subclass is configure settiong
 * to permitted_uri_char addition '='.
 *
 * $config['permitted_uri_chars'] = '= a-z 0-9~%.:_-';
 *
 * this MY_session subclass is config routes settiong
 * to 'SESSID' additions.
 *
 * $route['(.*)SESSID=.*$'] = "$1";
 */

/**
 * MY_Session
 *
 * @package    example.com
 * @subpackage CI_Session
 * @author    name <xxxxxxxxxxx@gmail.com>
 */
class MY_Session extends CI_Session {

	var $couldnt_read_cookie = FALSE;

	/**
	 * __construct
	 *
	 * @access public
	 * @return void
	 */
	function __construct()
	{
		parent::__construct();
	}

	// --------------------------------------------------

	/**
	 * Fetch the current session data if it exists
	 *
	 * @access	public
	 * @return	bool
	 */
	function sess_read()
	{
		// Fetch the cookie
		$session = $this->CI->input->cookie($this->sess_cookie_name);

		// No cookie?  Goodbye cruel world!...
		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
			{
				$this->CI->db->where('session_id', str_replace("SESSID=", "", $url_session[0]));
				$query = $this->CI->db->get($this->sess_table_name);

				// No result?  Kill it!
				if ($query->num_rows() == 0)
				{
					$this->sess_destroy();
					return FALSE;
				}
				foreach ($query->result_array() as $row)
				{
					$session['session_id']    = $row['session_id'];
					$session['last_activity'] = $row['last_activity'];
					$session['user_agent']    = $row['user_agent'];
					$session['ip_address']    = $row['ip_address'];
				}
			}
		}
		else
		{
			// Decrypt the cookie data
			if ($this->sess_encrypt_cookie == TRUE)
			{
				$session = $this->CI->encrypt->decode($session);
			}
			else
			{
				// encryption was not used, so we need to check the md5 hash
				$hash	 = substr($session, strlen($session)-32); // get last 32 chars
				$session = substr($session, 0, strlen($session)-32);

				// Does the md5 hash match?  This is to prevent manipulation of session data in userspace
				if ($hash !==  md5($session.$this->encryption_key))
				{
					log_message('error', 'The session cookie data did not match what was expected. This could be a possible hacking attempt.');
					$this->sess_destroy();
					return FALSE;
				}
			}
			// Unserialize the session array
			$session = $this->_unserialize($session);
		}


		// Is the session data we unserialized an array with the correct format?
		if ( ! is_array($session) OR ! isset($session['session_id']) OR ! isset($session['ip_address']) OR ! isset($session['user_agent']) OR ! isset($session['last_activity']))
		{
			$this->sess_destroy();
			return FALSE;
		}

		// Is the session current?
		if (($session['last_activity'] + $this->sess_expiration) < $this->now)
		{
			$this->sess_destroy();
			return FALSE;
		}

		// Does the IP Match?
		if ($this->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->sess_match_useragent == TRUE AND trim($session['user_agent']) != trim(substr($this->CI->input->user_agent(), 0, 120)))
		{
			$this->sess_destroy();
			return FALSE;
		}

		// Is there a corresponding session in the DB?
		if ($this->sess_use_database === TRUE)
		{
			$this->CI->db->where('session_id', $session['session_id']);

			if ($this->sess_match_ip == TRUE)
			{
				$this->CI->db->where('ip_address', $session['ip_address']);
			}

			if ($this->sess_match_useragent == TRUE)
			{
				$this->CI->db->where('user_agent', $session['user_agent']);
			}

			$query = $this->CI->db->get($this->sess_table_name);

			// No result?  Kill it!
			if ($query->num_rows() == 0)
			{
				$this->sess_destroy();
				return FALSE;
			}

			// Is there custom data?  If so, add it to the main session array
			$row = $query->row();
			if (isset($row->user_data) AND $row->user_data != '')
			{
				$custom_data = $this->_unserialize($row->user_data);

				if (is_array($custom_data))
				{
					foreach ($custom_data as $key => $val)
					{
						$session[$key] = $val;
					}
				}
			}
		}

		// Session is valid!
		$this->userdata = $session;
		unset($session);

		return TRUE;
	}

	// --------------------------------------------------

	/**
	* sess_write
	*
	* @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;

			$sessid = $this->userdata['session_id'];
			$this->CI->config->set_item ('url_suffix','/SESSID='. $sessid. config_item ('url_suffix'));
		}

		//Save userdata in database
		if ($this->sess_use_database === TRUE)
		{
			$custom_userdata = $this->userdata;

			foreach (array('session_id','ip_address','user_agent','last_activity') as $val)
			{
				unset($custom_userdata[$val]);
			}

			$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'],
						"user_data" => serialize ( $custom_userdata )
						);
			$this->CI->db->where ( "session_id", $this->userdata ( 'session_id' ) );
			$this->CI->db->update ( $this->sess_table_name, $set );
		}
	}
}

/* End of file MY_Session.php */
/* Location: ./application/libraries/MY_Session.php */
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?