소스 : https://github.com/braverokmc79/Codeigniter_project2
Codeigniter 3.15
7.1 세션 구조
일반적인 경우 쿠키를 암호화하여 저장하지 않아서 쿠키 파일을 열어보면 사용자 아이디, 이름, 전화번호 등을 볼 수 있습니다.
무조건 데이터베이스 세션을 사용할 필요는 없지만 보안 강화를 위해 서버 자원을 조금 더 사용하더라도 사용하는 것이 좋습니다.
먼저 데이터베이스 세션을 사용하기 위해 설정을 바꿉니다.
1. /application/config/config.php
$config['sess_driver'] = 'database';
$config['sess_cookie_name'] = 'ci_session';
$config['sess_expiration'] = 7200;
$config['sess_save_path'] = NULL;
$config['sess_match_ip'] = FALSE;
$config['sess_time_to_update'] = 300;
$config['sess_regenerate_destroy'] = FALSE;
$config['sess_use_database']=TRUE;
$config['sess_table_name']='ci_sessions';
1. 초기값은 FALSE 입니다. 데이터베이스 세션을 사용하기 위해 TRUE 로 수정합니다.
2. DB 세션 사용 시 코어에서 사용하는 테이블명입니다. 기본 값은 ci_sessions 인데 원하는 이름으로 바꿔서 사용해도 됩니다.
여기서는 기본 값을 사용합니다.
2. 다음은 MySQL ci_book 데이터베이스에 ci_sessions 테이블을 생성해야 합니다. MySQL 콘솔에 접속한 후에 다음 SQL 문을 이용해 테이블을 생성합니다.
CI 에서 제공하는 세션 기본 데이터 삽입 컬럼 명
INSERT INTO `ci_sessions` (`id`, `ip_address`, `timestamp`, `data`)
-- 테이블 ci_book의 구조를 덤프합니다. ci_sessions
DROP TABLE IF EXISTS `ci_sessions`;
CREATE TABLE IF NOT EXISTS `ci_sessions` (
`id` varchar(200) not null default '0',
`ip_address` varchar(16) NOT NULL DEFAULT '0',
`user_agent` varchar(120) NOT NULL,
`last_activity` int(10) unsigned NOT NULL DEFAULT '0',
`data` TEXT,
`timestamp` DATETIME DEFAULT now(),
PRIMARY KEY (`id`),
KEY `last_activity_idx` (`last_activity`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
그리고 세션과 데이터베이스를 계속 이용해 프로그램을 할 것이라 이 라이브러리를 자동 로드하도록 하겠습니다.
3 . autoload.php
$autoload['libraries'] = array('database', 'session');
$autoload['helper'] = array('date');
모든 라이브러리와 헬퍼를 자동 로딩하면 프로그램할 때 신경 쓰지 않아도 에러 없이 프로그래밍할 수 있는 반면에 많은 메모리를 사용하게
됩니다. 그래서 autoload.php 에는 최소한의 라이브러리와 헬퍼만 로딩하기 바랍니다.
7.1 로그인
1. 로그인 페이지에서 아이디, 비밀번호를 입력 후 폼을 전송합니다.
2. 로그인 컨트롤러에서 전송받은 아이디, 비밀번호와 매치되는 데이터가 있는지 검증(모델 이용)합니다.
3. 검증된 아이디가 있다면 아이디, 이메일 등 개인정보를 넣어 세션을 생성합니다.
4. 이후 사용자 인증이 필요한 페이지에서 세션으로 인증 여부를 체크하여 실행합니다.
auth.php
class Auth extends CI_Controller {
function __construct()
{
parent::__construct();
$this->load->model('auth_m');
//CSRF 방지
$this->load->helper('form');
}
//주소에서 메서드가 생략되었을 때 실행되는 기본 메서드
public function index()
{
$this->login();
}
/*
사이트 헤더, 푸터가 자동으로 추가된다.
*/
public function _remap($method)
{
//헤더 include
$this->load->view('header_v');
if(method_exists($this, $method))
{
$this->{"{$method}"}();
}
//푸터 include
$this->load->view('footer_v');
}
/*
* 로그인 처리
*/
public function login()
{
//폼 검증 라이브러리 로드
$this->load->library('form_validation');
$this->load->helper('alert');
//폼 검증할 필드와 규칙 사전 정의
$this->form_validation->set_rules('username', '아이디', 'required|alpha_numeric');
$this->form_validation->set_rules('password', '비밀번호', 'required');
echo '<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />';
if($this->form_validation->run()==TRUE)
{
$auth_data=array(
'username' => $this->input->post('username', TRUE),
'password' =>$this->input->post('password', TRUE)
);
$result =$this->auth_m->login($auth_data);
if($result)
{
//세션 생성
$newdata = array(
'username' => $result->username,
'email' =>$result->email,
'logged_in'=>TRUE
);
$this->session->set_userdata($newdata);
alert('로그인 되었습니다.', '/todo/board/lists/ci_board/page/1');
exit;
}
else
{
//실패 시
alert('아이디나 비밀번호를 확인해 주세요.', '/todo/auth');
}
}
else
{
//쓰기 폼 view 호출
$this->load->view('auth/login_v');
}
}
1. 사용자 인증 모델과 폼 헬퍼를 로딩합니다.
$this->load->model('auth_m');
//CSRF 방지
$this->load->helper('form');
2. 로그인을 담당하는 함수를 작성합니다.
public function login()
3. 아이디, 비밀번호를 반드시 입력해야 하므로 폼 검증 라이브러리를 사용합니다.
//폼 검증 라이브러리 로드
$this->load->library('form_validation');
$this->load->helper('alert');
4. 폼 검증 규칙을 설정합니다. 아이디는 필수, 영문과 숫자만 가능하고 비밀번호는 필수 필드로만 설정 했습니다.
//폼 검증할 필드와 규칙 사전 정의
$this->form_validation->set_rules('username', '아이디', 'required|alpha_numeric');
$this->form_validation->set_rules('password', '비밀번호', 'required');
5. 폼 검증이 성공했을 경우(아이디, 비밀번호가 모두 입력돼서 전송된 경우)의 처리입니다.
if($this->form_validation->run()==TRUE)
{
6. 모델에 데이터를 전달하기 위해 보안처리 후 배열에 담습니다.
$auth_data=array(
'username' => $this->input->post('username', TRUE),
'password' =>$this->input->post('password', TRUE)
);
7. 모델에서 전송된 아이디, 비밀번호와 맞는 데이터가 있는지 검사하여 있으면 해당 데이터(username, email)를 반환하고 없다면
FALSE 를 반환합니다.
$result =$this->auth_m->login($auth_data);
8. 아이디, 비밀번호가 맞는 경우의 처리이며 세션을 생성하기 위해 아이디(username) 와 email, 로그인 여부(logged_in) 를 배열로
만듭니다.
//세션 생성
$newdata = array(
'username' => $result->username,
'email' =>$result->email,
'logged_in'=>TRUE
);
9. 8번의 배녈 데이터로 세션을 생성합니다.
$this->session->set_userdata($newdata);
10. 아이디나 비밀번호가 맞지 않을 경우의 처리입니다.
else
{
//실패 시
alert('아이디나 비밀번호를 확인해 주세요.', '/todo/auth');
}
11. 로그인 입력 폼을 출력하는 분개 처리입니다.
//쓰기 폼 view 호출
$this->load->view('auth/login_v');
auth_m.php
<?php defined('BASEPATH') OR exit('No direct script access allowed');
/*
사용자 인증 모델
*/
class Auth_m extends CI_Model
{
function __construct()
{
parent::__construct();
}
//아이디 비빌번호 체크
function login($auth)
{
$sql =" select username, email from USERS where username =? and password =?";
$query=$this->db->query($sql,
array(
'username'=>$auth['username'],
'password'=>$auth['password']
)
);
if($query->num_rows()>0)
{
// 맞는 데이터가 있다면 해당 내용 반환
return $query->row();
}
else
{
// 맞는 데이터가 없을 경우
return FALSE;
}
}
}
header_v.php
<?php
1. if(@$this->session->userdata('logged_in')==TRUE)
{
?>
2. <?php echo $this->session->userdata('username') ?> 님 환영합니다.
<a href="/todo/auth/logout" class="btn">로그아웃</a>
<?php
}else {
?>
3. <a href="/todo/auth/" class="btn btn-danger">로그인</a>
<?php } ?>
1. 로그인 여부를 체크하는 세션 값입니다. 로그인 컨트롤러에서 로그인에 성공했을 때 배열로 선언한 변수 중 하나입니다. 세션 라이브러리가
자동 로드된 상태이기 때문에 컨트롤러, 모델, 뷰에서 $this->session 형태로 사용할 수 있습니다.
2. 컨트롤러에서 만든 3객의 세션 값 중 username 을 불러옵니다.
3. 로그인 버튼과 링크입니다.
login_v.php
<?php
$attributes = array(
'class' => 'form-horizontal',
'id' => 'auth_login');
echo form_open('/auth/login', $attributes);
?>
<fieldset>
<legend>로그인</legend>
<div class="control-group">
<label for="input01" class="control-label">아이디</label>
<div class="controls">
<input type="text" class="input-xlarge" id="input01" name="username"
value="<?php echo set_value('username'); ?>" >
<p class="help-block">
<?php echo form_error('username');?>
</p>
</div>
<label for="input02" class="control-label">비밀번호</label>
<div class="controls">
<input type="password" class="input-xlarge" id="input02" name="password"
value="<?php echo set_value('password'); ?>" >
<p class="help-block">
<?php echo form_error('password'); ?>
</p>
</div>
<div class="form-actions">
<button type="submit" class="btn btn-primary">확인</button>
<button class="btn" onclick="document.location.reload()">취소</button>
</div>
</div>
</fieldset>
1. CSRF 방지 처리를 위한 폼 헬퍼의 form_open() 함수 사용.
<?php
$attributes = array(
'class' => 'form-horizontal',
'id' => 'auth_login');
echo form_open('/auth/login', $attributes);
?>
2. 컨트롤러에서 선언한 룰의 이름과 동일하게 input 태그의 naem 을 username 으로 작성
set_value('username');
3. input 태그를 작성
4. 폼 검증에 실패했을 경우 에러 메시지를 표시
validation_errors();
<?php echo form_error('username');?>
$this->session->userdata('username') 은 user_data 필드의 내용 중에서 username 에 해당하는 값을 반환합니다.
7.3 로그아웃
public function logout()
{
$this->load->helper('alert');
$this->session->sess_destroy();
echo '<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />';
alert('로그아웃 되었습니다', '/todo/board/lists/ci_board/page/1');
}
7.4.1 게시판 쓰기에 사용자 인증 적용하기
board.php
function write()
{
//폼 검증 라이브러리 로드
$this->load->library('form_validation');
$this->load->helper('alert');
if(@$this->session->userdata('logged_in')==TRUE)
{
'user_id'=>$this->session->userdata('username')
else
{
alert('로그인 후 작성하세요', '/todo/auth/login');
exit;
}
function write()
{
//폼 검증 라이브러리 로드
$this->load->library('form_validation');
$this->load->helper('alert');
if(@$this->session->userdata('logged_in')==TRUE)
{
// 폼 검증할 필드와 규칙 사전 정의
$this->form_validation->set_rules('subject', '제목', 'required|xss_clean');
$this->form_validation->set_rules('contents', '내용', 'required');
//경고창 헬퍼 로딩
$this->load->helper('alert');
echo '<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />';
if($_POST)
{
//주소중에서 page 세그먼트가 있는지 검사하기 위해 주소를 배열로 변환
/* $uri_array = $this->segment_explode($this->uri->uri_string());
if( in_array('page', $uri_array) )
{
$pages = urldecode($this->url_explode($uri_array, 'page'));
}
else
{
$pages = 1;
}
*/
if(!$this->input->post('subject', TRUE) OR !$this->input->post('contents', TRUE))
{
//글 내용이 없을 경우, 프로그램단에서 한 번 더 체크
alert('비정상적인 접근입니다.', '/todo/board/view/'.$this->uri->segment(3));
exit;
}
$write_data=array(
'subject'=>$this->input->post('subject', TRUE),
'contents'=>$this->input->post('contents', TRUE),
'table' =>'ci_board',
'user_id'=>$this->session->userdata('username')
);
$result =$this->board_m->insert_board($write_data);
if($result)
{
//글 작성 성공시 게시판 목록으로
alert('입력되었습니다.', '/todo/board/lists/');
exit;
}
else
{
//글 실패 시 게시물 목록으로
alert('다시 입력해 주세요.', '/todo/board/lists/');
exit;
}
}
else
{
//쓰기 폼 view 호출
$this->load->view('board/write_v');
}
}
else
{
alert('로그인 후 작성하세요', '/todo/auth/login');
exit;
}
}
board_m.php
//쓰기
function insert_board($arrays)
{
$insert_array= array(
'board_pid' => 0, //원글이라 0을 입력, 댓글일 경우 번호 입력
'user_id' =>$arrays['user_id'],
'user_name' =>'마카로닉스',
'subject'=>$arrays['subject'],
'contents'=>$arrays['contents'],
'reg_date'=>date("Y-m-d H:i:s")
);
$result=$this->db->insert($arrays['table'], $insert_array);
//결과 반환
return $result;
}
7.4.2 게시판 수정에 사용자 인증 적용하기
board.php
function modify()
{
//경고창 헬퍼 로딩
$this->load->helper('alert');
echo '<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />';
//현재 url 페이지 번호 가져오기
$pages=$this->_pageNumber();
if(@$this->session->userdata('logged_in')==TRUE)
{
//수정하려는 글의 작성자가 본인인지 검증
$writer_id=$this->board_m->writer_check();
if($writer_id->user_id != $this->session->userdata('username'))
{
alert('본인이 작성한 글이 아닙니다.', '/todo/board/lists/ci_board/page/'.$pages);
exit;
}
~~~
~~~~~
~~~
}
else{
alert('로그인 후 수정하세요.' , '/todo/auth/login/');
exit;
}
}
board_.m.php
function writer_check()
{
$sql=" select user_id from CI_BOARD where board_id = ?" ;
$query=$this->db->query($sql, array('board_id'=>$this->uri->segment(4)));
return $query->row();
}
7.4.3 게시판 삭제에 사용자 인증 적용하기
board.php
if(@$this->session->userdata('logged_in')==TRUE)
{
//삭제하려는 글의 작성자가 본인이지 검증
$writer_id=$this->board_m->writer_check();
if($writer_id->user_id != $this->session->userdata('username'))
{
alert('본인이 작성한 글이 아닙니다.', '/todo/board/view/'.$this->uri->segment(4).'/ci_board/page/'.$this->uri->segment(7));
exit;
}
function delete()
{
echo '<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />' ;
//경고창 헬퍼 로딩
$this->load->helper('alert');
$pages=$this->_pageNumber();
//게시물 목록으로 돌아가기
if(@$this->session->userdata('logged_in')==TRUE)
{
//삭제하려는 글의 작성자가 본인이지 검증
$writer_id=$this->board_m->writer_check();
if($writer_id->user_id != $this->session->userdata('username'))
{
alert('본인이 작성한 글이 아닙니다.', '/todo/board/view/'.$this->uri->segment(4).'/ci_board/page/'.$this->uri->segment(7));
exit;
}
//게시물 번호에 해당하는 게시물 삭제
$return=$this->board_m->delete_content('ci_board',$this->uri->segment(4));
if($return)
{
//삭제가 성공한 경우
alert('삭제 되었습니다.', '/todo/board/lists/ci_board/page/'.$pages);
exit;
}
else
{
//삭제가 실패한 경우
alert('삭제 실패하였습니다.', '/todo/board/lists/ci_board/page/'.$pages);
exit;
}
}else
{
alert('로그인 후 삭제 하세요', '/todo/auth/login/');
exit;
}
}
만들면서 배우는 CodeIgniter 프레임워크
한빛미디어
집필서
판매중
- 저자 :변종원
- 출간 :2013-07-16
- 페이지 :432 쪽
- ISBN :9788968480263
댓글 ( 4)
댓글 남기기