You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

CodeIgniter 4:如何用Cookie与AJAX实现登录后用户数据存储

  • Cookie是浏览器保存在本地的小型文本数据,用于持久化用户状态(比如自动登录)
  • 绝对禁止明文存储密码:这会导致严重的安全风险,建议存储加密后的用户标识(比如用户ID + 加密令牌)
  • 核心属性:
    • 有效期:控制Cookie的存活时间(单位:秒)
    • 路径:指定哪些URL可以访问该Cookie(设为/表示全站可用)
    • Secure:仅在HTTPS连接下发送Cookie
    • HttpOnly:禁止JS读取Cookie,防范XSS攻击
    • SameSite:限制Cookie跨域发送,减少CSRF风险
  1. 设置Cookie:
    使用response()->setCookie()方法,参数需匹配业务场景:
// 设置7天有效期的全站Cookie,开启安全防护
response()->setCookie([
    'name'     => 'user_auth',
    'value'    => '加密后的用户标识',
    'expire'   => 604800, // 7*24*3600秒
    'path'     => '/',
    'secure'   => env('CI_ENVIRONMENT') === 'production',
    'httponly' => true,
    'samesite' => 'Lax'
]);
  1. 获取Cookie:
$authCookie = $this->request->getCookie('user_auth');
  1. 删除Cookie:
    需与设置时的路径、域名参数一致,才能彻底清除:
response()->deleteCookie('user_auth', '/');
问题排查与代码修正

你的AJAX登录失效,大概率是Cookie参数设置错误 + 明文存密码的逻辑问题,以下是完整修复方案:

1. 数据库前置准备

  • 确保students表的password字段存储加密后的密码(用password_hash()生成)
  • 新增remember_token字段(varchar(64)),用于存储自动登录的验证令牌

2. 登录控制器(Auth.php)

<?php

namespace App\Controllers;

use App\Models\StudentModel;
use CodeIgniter\Controller;

class Auth extends Controller
{
    protected $studentModel;

    public function __construct()
    {
        $this->studentModel = new StudentModel();
    }

    // 登录页(含自动登录逻辑)
    public function index()
    {
        $authCookie = $this->request->getCookie('user_auth');
        if ($authCookie) {
            // 解密Cookie内容:格式为「用户ID|验证令牌」
            $decrypted = decrypt($authCookie);
            list($userId, $token) = explode('|', $decrypted);

            // 验证令牌有效性
            $student = $this->studentModel->find($userId);
            if ($student && $student['remember_token'] === $token) {
                // 自动登录,写入Session
                session()->set('student_id', $userId);
                session()->set('student_email', $student['email']);
                return redirect()->to('/dashboard');
            }
            // 令牌无效,清理Cookie
            response()->deleteCookie('user_auth', '/');
        }

        return view('auth/login');
    }

    // AJAX登录处理
    public function login()
    {
        $this->response->setContentType('application/json');
        $data = $this->request->getJSON(true) ?? $this->request->getPost();

        // 表单验证
        $rules = [
            'email' => 'required|valid_email',
            'password' => 'required'
        ];
        if (!$this->validate($rules)) {
            return $this->response->setJSON([
                'status' => 'error',
                'message' => $this->validator->getErrors()
            ]);
        }

        // 查询用户并验证密码
        $student = $this->studentModel->where('email', $data['email'])->first();
        if (!$student || !password_verify($data['password'], $student['password'])) {
            return $this->response->setJSON([
                'status' => 'error',
                'message' => '邮箱或密码错误'
            ]);
        }

        // 生成自动登录令牌并更新数据库
        $rememberToken = bin2hex(random_bytes(32));
        $this->studentModel->update($student['id'], ['remember_token' => $rememberToken]);

        // 加密并设置Cookie
        $cookieValue = encrypt($student['id'] . '|' . $rememberToken);
        response()->setCookie([
            'name'     => 'user_auth',
            'value'    => $cookieValue,
            'expire'   => 604800,
            'path'     => '/',
            'secure'   => env('CI_ENVIRONMENT') === 'production',
            'httponly' => true,
            'samesite' => 'Lax'
        ]);

        // 写入Session
        session()->set('student_id', $student['id']);
        session()->set('student_email', $student['email']);

        return $this->response->setJSON([
            'status' => 'success',
            'message' => '登录成功',
            'redirect' => '/dashboard'
        ]);
    }

    // 登出处理
    public function logout()
    {
        session()->destroy();
        response()->deleteCookie('user_auth', '/');
        return redirect()->to('/auth');
    }
}

3. StudentModel.php 配置

<?php

namespace App\Models;

use CodeIgniter\Model;

class StudentModel extends Model
{
    protected $table = 'students';
    protected $primaryKey = 'id';
    protected $allowedFields = ['email', 'password', 'remember_token'];
    protected $returnType = 'array';
}

4. 前端AJAX代码(登录页)

确保请求正确处理响应,同域下默认携带Cookie,跨域需添加withCredentials: true:

$('#loginForm').submit(function(e) {
    e.preventDefault();
    $.ajax({
        url: '/auth/login',
        method: 'POST',
        data: $(this).serialize(),
        dataType: 'json',
        // 跨域场景需启用下面一行
        // xhrFields: { withCredentials: true },
        success: function(res) {
            res.status === 'success' ? window.location.href = res.redirect : alert(res.message);
        },
        error: function() {
            alert('请求失败,请重试');
        }
    });
});

5. Dashboard登录验证

<?php

namespace App\Controllers;

use App\Models\StudentModel;

class Dashboard extends Controller
{
    public function index()
    {
        // 优先验证Session,无Session则检查Cookie自动登录
        if (!session()->get('student_id')) {
            $authCookie = $this->request->getCookie('user_auth');
            if (!$authCookie) {
                return redirect()->to('/auth');
            }

            $decrypted = decrypt($authCookie);
            list($userId, $token) = explode('|', $decrypted);
            $student = model(StudentModel::class)->find($userId);
            
            if (!$student || $student['remember_token'] !== $token) {
                response()->deleteCookie('user_auth', '/');
                return redirect()->to('/auth');
            }

            session()->set('student_id', $userId);
            session()->set('student_email', $student['email']);
        }

        return view('dashboard/index');
    }
}

常见失效原因总结

  1. Cookie路径错误:未设置path: '/'导致其他页面无法读取Cookie
  2. HttpOnly与前端读取冲突:若前端尝试读取HttpOnly Cookie会失败(登录状态应由后端验证,前端无需读取)
  3. 明文密码存储:逻辑错误+安全风险,导致验证失败
  4. 响应未正确返回:AJAX请求中设置Cookie后需返回JSON响应,不能提前跳转

内容的提问来源于stack exchange,提问作者Van Y Pham

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.02 16:35:22