資料表結構
CREATE TABLE `user` (
`id` INT AUTO_INCREMENT PRIMARY KEY,
`num` VARCHAR(50) NOT NULL UNIQUE COMMENT '用戶帳號',
`password` CHAR(32) NOT NULL COMMENT 'MD5 加密密碼',
`name` VARCHAR(50) COMMENT '暱稱',
`email` VARCHAR(100) COMMENT '電子郵件',
`addtime` INT COMMENT '註冊時間戳',
`status` TINYINT DEFAULT 0 COMMENT '0待審 1正常 2禁用'
);
控制器核心代碼
namespace Home\Controller;
use Think\Controller;
class LoginController extends Controller {
// 登入處理
public function signin() {
if (IS_GET) { $this->display(); return; }
$num = I('num');
$pwd = I('password');
$user = M('user')->where(['num'=>$num])->find();
if (!$user) { $this->error('用戶不存在', U('signup')); return; }
if (md5($pwd) !== $user['password']) { $this->error('密碼錯誤'); return; }
switch ($user['status']) {
case 0: $this->error('待審核,請聯繫管理員'); break;
case 2: $this->error('帳號已禁用,請聯繫管理員'); break;
default:
$this->autoLogin($user);
$this->success('登入成功', U('Index/index'));
}
}
// 自動登入寫入 Session
private function autoLogin($user) {
$auth = [
'uid' => $user['id'],
'num' => $user['num'],
'role' => 'user'
];
session('user_auth', $auth);
session('user_auth_sign', data_auth_sign($auth));
}
// 註冊處理
public function signup() {
if (is_user_login()) { $this->redirect('Index/index'); }
if (IS_GET) { $this->display(); return; }
$num = I('num');
if (M('user')->where(['num'=>$num])->find()) {
$this->success('已註冊,請登入', U('signin')); return;
}
$data = [
'num' => $num,
'password' => md5(I('password')),
'name' => I('name'),
'email' => I('email'),
'addtime' => time(),
];
M('user')->add($data) ? $this->success('註冊成功', U('signin')) : $this->error('註冊失敗');
}
// 登出
public function logout() {
if (is_user_login()) {
session('user_auth', null);
session('user_auth_sign', null);
session('[destroy]');
$this->success('登出成功', U('signin'));
} else { $this->redirect('signin'); }
}
// 忘記密碼(郵箱驗證重置)
public function wjpas() {
if (IS_GET) { $this->display(); return; }
$num = I('num');
$email = I('email');
$newPwd = md5(I('password'));
$user = M('user')->where(['num'=>$num])->find();
if (!$user) { $this->error('用戶不存在', U('signup')); return; }
if ($email !== $user['email']) { $this->error('郵箱不匹配'); return; }
M('user')->where(['num'=>$num])->save(['password'=>$newPwd]);
$this->success('密碼重置成功', U('signin'));
}
}
安全性補充建議
- 密碼建議使用
password_hash() + password_verify() 替代 MD5
- 註冊/重置流程加入簡訊/郵件驗證碼
- 登入介面增加圖形驗證碼,防暴力破解
- 敏感操作記錄審計日誌