專案結構
- Controller:
application/controllers/Login.php
- View:
application/views/login.php
- Model:使用 Active Record 直接在 Controller 操作(簡化範例)
- 資料表:
uc_user
資料表結構
CREATE TABLE `uc_user` (
`id` int(11) unsigned zerofill NOT NULL AUTO_INCREMENT,
`user` varchar(20) NOT NULL,
`pass` char(32) NOT NULL,
`role` enum('root','normal') NOT NULL DEFAULT 'normal',
`del` decimal(1,0) NOT NULL DEFAULT '0',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
Controller:Login.php
<?php
class Login extends CI_Controller {
private $pass = '';
public function __construct() {
parent::__construct();
$this->load->helper(['form', 'url']);
$this->load->library('session');
}
public function index() {
$this->load->view('login');
}
public function formsubmit() {
$this->load->library('form_validation');
$this->form_validation->set_rules('username', 'Username', 'required');
$this->form_validation->set_rules('password', 'Password', 'required');
if ($this->form_validation->run() === FALSE) {
$this->load->view('login');
return;
}
if (isset($_POST['submit']) && !empty($_POST['submit'])) {
$data = [
'user' => $_POST['username'],
'pass' => md5($_POST['password']) // 實務建議用 password_hash()
];
$sessionData = [
'username' => $data['user'],
'userip' => $_SERVER['REMOTE_ADDR'],
'luptime' => time()
];
if ($_POST['submit'] === 'login') {
$query = $this->db->get_where('uc_user', ['user' => $data['user']], 1);
foreach ($query->result() as $row) {
$this->pass = $row->pass;
}
if ($this->pass === $data['pass']) {
$this->session->set_userdata($sessionData);
$this->load->view('usercenter', $data);
} else {
$this->session->set_flashdata('error', '帳號或密碼錯誤');
$this->load->view('login');
}
} elseif ($_POST['submit'] === 'register') {
$this->db->insert('uc_user', $data);
$this->session->set_userdata($sessionData);
$this->load->view('usercenter', $data);
} else {
$this->session->sess_destroy();
$this->load->view('login');
}
}
}
}
View:login.php
<html>
<head><meta charset="utf-8"><title>登入/註冊</title></head>
<body>
<?php echo validation_errors(); ?>
<?php echo form_open('login/formsubmit'); ?>
<table>
<tr>
<td>用戶名</td>
<td><input type="text" name="username"></td>
</tr>
<tr>
<td>密碼</td>
<td><input type="password" name="password"></td>
</tr>
<tr>
<td><input type="submit" name="submit" value="login"></td>
<td><input type="submit" name="submit" value="register"></td>
</tr>
</table>
</form>
</body>
</html>
安全性強化建議(生產環境必做)
- 密碼雜湊:使用
password_hash() / password_verify() 取代 MD5。
// 註冊時
$hash = password_hash($_POST['password'], PASSWORD_DEFAULT);
// 登入時
if (password_verify($_POST['password'], $row->pass)) { ... }
- CSRF 保護:
config.php 開啟 $config['csrf_protection'] = TRUE;,表單加入 security->get_csrf_token_name(), $this->security->get_csrf_hash()); ?>
- SQL 注入防護:Active Record 內建參數綁定,避免字串拼接 SQL。
- 輸入驗證:加入
alpha_numeric、min_length[6]、max_length[20] 等規則。
- Session 安全:設定
$config['sess_use_database'] = TRUE、$config['sess_match_ip'] = TRUE、$config['sess_encrypt_cookie'] = TRUE。
- 登入限流:記錄失敗次數,超過鎖定 15 分鐘。
擴充方向
- 整合 Tank Auth、Ion Auth 成熟權限庫
- 加入 Remember Me、Email 驗證、密碼重設 功能
- 採用 HMVC 模組化架構分離會員模組