프로그래밍/CodeIgniter

[CodeIgniter] IP 주소 가져오기 (Input 확장)

떨어지는 용 2019. 1. 22. 23:41

▶CodeIgniter IP 주소 가져오기 (Input 확장)



▶설명


코드이그나이터에서 제공하는 현재 사용자의 IP 주소를 가져오는 함수에 대해 알아보도록 하겠습니다.

또한, IP 주소를 가져올 때 정확도를 높이기 위한 개선 방법 또한 알아보도록 하겠습니다.


▶IP 주소 가져오기


현재 사용자의 IP 주소 가져오기는 정말 간단합니다.


사용법

$this->input->ip_address();

현재 사용자의 IP 주소를 반환합니다.

만약 유효하지 않은 IP 주소에 경우 '0.0.0.0' 주소를 반환합니다.


그렇지만, 위에 함수를 그대로 사용하면 IP 주소를 못 가져오는 경우가 발생할 수도 있습니다.

현재 사용자가 프록시 서버를 사용중인 경우가 대표적인 예입니다.

그러면 이제 IP 주소를 가져오는 것에 대한 개선 방법을 알아보도록 하겠습니다.


▶코어 Input 확장


IP 주소를 가져오는 함수는 system/core/Input.php라는 파일에 CI_Input이라는 클래스에 위치하고 있습니다.

시스템 코어 파일을 직접 수정하는 것은 좋지 않기 때문에,

코어 Input을 확장하여 IP 주소 가져오기 함수를 개선하도록 하겠습니다.


나만의 접두어 확인

application/config/config.php

$config['subclass_prefix'] = 'MY_';


접두어가 'MY_' 이기 때문에 확장을 위해 생성하는 로그 파일 이름은 'MY_Log'입니다.


※ 다른 이름으로 사용하고 싶으시다면 접두어를 변경하시기 바랍니다.


※ 'CI_' 는 코드이그나이터 기본 접두어이므로 사용해서는 안됩니다!!!


확장 파일 추가

저는 접두어가 'MY_'이므로 MY_Input.php로 추가하겠습니다.

application/core/MY_Input.php

<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');

class MY_Input extends CI_Input
{
    public function __construct()
    {
        parent::__construct();
    }
    
    public function ip_address()
    {
        if($this->ip_address !== FALSE)
        {
            return $this->ip_address;
        }

        if( ! empty($this->server('HTTP_CLIENT_IP')) && $this->valid_ip($this->server('HTTP_CLIENT_IP')) )
        {
            $this->ip_address = $this->server('HTTP_CLIENT_IP');
        }
        else if( ! empty($this->server('HTTP_X_FORWARDED_FOR')) && $this->valid_ip($this->server('HTTP_X_FORWARDED_FOR')) )
        {
            $this->ip_address = $this->server('HTTP_X_FORWARDED_FOR');
        }
        else if( ! empty($this->server('HTTP_X_FORWARDED')) && $this->valid_ip($this->server('HTTP_X_FORWARDED')) )
        {
            $this->ip_address = $this->server('HTTP_X_FORWARDED');
        }
        else if( ! empty($this->server('HTTP_FORWARDED_FOR')) && $this->valid_ip($this->server('HTTP_FORWARDED_FOR')) )
        {
            $this->ip_address = $this->server('HTTP_FORWARDED_FOR');
        }
        else if( ! empty($this->server('HTTP_FORWARDED')) && $this->valid_ip($this->server('HTTP_FORWARDED')) )
        {
            $this->ip_address = $this->server('HTTP_FORWARDED');
        }
        else
        {
            parent::ip_address();
        }
        
        return $this->ip_address();
    }
}


이제 기존과 동일하게 $this->input->ip_address(); 함수를 호출해도,

확장된 MY_Input 클래스에 위치한 ip_address 함수를 먼저 호출할 것입니다.


  1. HTTP_CLIENT_IP
  2. HTTP_X_FORWARDED_FOR
  3. HTTP_X_FORWARDED
  4. HTTP_FORWARDED_FOR
  5. HTTP_FORWARDED

위의 값들은 보내지 않을 수도 있는 값이기 때문에,

값 존재 여부와 함께 IP 주소 유효성 검사도 함께 처리하도록 작성했습니다.


▶마치며


위에 코드에 문제점이나, 추가적인 개선 방법이 존재하면 수정하도록 하겠습니다.