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

如何在CodeIgniter中将Token从一个控制器传递到另一个控制器?

在CodeIgniter中从其他控制器获取并验证JWT Token

一、前端传递Token的核心方式

用户登录拿到Token后,前端需要在后续所有需要鉴权的请求中,将Token放在HTTP请求头的Authorization字段里,格式固定为:

Authorization: Bearer <你的Token字符串>

二、目标控制器中获取并验证Token的实现

以你提到的/me接口为例,创建MeController来获取当前用户信息,示例代码如下:

<?php

namespace App\Controllers;

use CodeIgniter\RESTful\ResourceController;
use CodeIgniter\API\ResponseTrait;
use Firebase\JWT\JWT;
use Firebase\JWT\Key;
use App\Models\UserModel;

class Me extends ResourceController
{
    use ResponseTrait;

    public function index()
    {
        // 1. 从请求头提取Authorization字段
        $authHeader = $this->request->getHeaderLine('Authorization');
        
        // 2. 校验Token是否存在、格式是否合规
        if (!$authHeader || !str_starts_with($authHeader, 'Bearer ')) {
            return $this->failUnauthorized('Token未提供或格式错误');
        }

        // 3. 剥离前缀,拿到纯Token字符串
        $token = substr($authHeader, 7);

        try {
            // 4. 验证并解析Token
            $key = getenv('TOKEN_SECRET');
            $payload = JWT::decode($token, new Key($key, 'HS256'));

            // 5. 根据Token中的用户ID获取用户信息(可选操作)
            $userModel = new UserModel();
            $user = $userModel->find($payload->uid);

            if (!$user) {
                return $this->failNotFound('用户不存在');
            }

            // 移除敏感字段后返回用户信息
            unset($user['password']);
            return $this->respond($user);

        } catch (\Firebase\JWT\ExpiredException $e) {
            return $this->failUnauthorized('Token已过期');
        } catch (\Exception $e) {
            return $this->failUnauthorized('Token无效');
        }
    }
}

三、封装公共验证逻辑(推荐)

为了避免重复写Token校验代码,可以把逻辑封装到BaseController中,让所有需要鉴权的控制器继承它:

<?php

namespace App\Controllers;

use CodeIgniter\Controller;
use Firebase\JWT\JWT;
use Firebase\JWT\Key;

class BaseController extends Controller
{
    protected $user;

    public function initController(\CodeIgniter\HTTP\RequestInterface $request, \CodeIgniter\HTTP\ResponseInterface $response, \Psr\Log\LoggerInterface $logger)
    {
        parent::initController($request, $response, $logger);
        
        // 登录接口跳过Token验证,其余接口自动校验
        if ($this->request->uri->getPath() !== 'login') {
            $this->validateToken();
        }
    }

    protected function validateToken()
    {
        $authHeader = $this->request->getHeaderLine('Authorization');
        
        if (!$authHeader || !str_starts_with($authHeader, 'Bearer ')) {
            $this->response->setStatusCode(401)->setJSON(['error' => 'Token未提供或格式错误'])->send();
            exit;
        }

        $token = substr($authHeader, 7);
        $key = getenv('TOKEN_SECRET');

        try {
            $payload = JWT::decode($token, new Key($key, 'HS256'));
            
            // 提前获取用户信息,供后续控制器直接使用
            $userModel = new \App\Models\UserModel();
            $this->user = $userModel->find($payload->uid);

            if (!$this->user) {
                $this->response->setStatusCode(404)->setJSON(['error' => '用户不存在'])->send();
                exit;
            }

        } catch (\Firebase\JWT\ExpiredException $e) {
            $this->response->setStatusCode(401)->setJSON(['error' => 'Token已过期'])->send();
            exit;
        } catch (\Exception $e) {
            $this->response->setStatusCode(401)->setJSON(['error' => 'Token无效'])->send();
            exit;
        }
    }
}

之后你的MeController可以简化为:

<?php

namespace App\Controllers;

use CodeIgniter\RESTful\ResourceController;
use CodeIgniter\API\ResponseTrait;

class Me extends BaseController
{
    use ResponseTrait;

    public function index()
    {
        // 直接使用父类中已验证通过的用户信息
        unset($this->user['password']);
        return $this->respond($this->user);
    }
}

关键优化提示

你当前Login控制器中的iat和nbf字段是固定值,建议改成动态时间戳并添加过期时间:

$payload = [
    'iat' => time(), // Token生成时间
    'nbf' => time(), // Token生效时间(立即生效)
    'exp' => time() + 3600, // Token过期时间(1小时后)
    'uid' => $user['id'],
    'email' => $user['email'],
];

添加exp字段后,JWT库会自动校验Token是否过期,无需手动判断。

内容的提问来源于stack exchange,提问作者Tommi Andrean

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 16:16:06