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

Codeigniter 4 Shield:如何签发访问令牌并解决空对象调用错误

解决CodeIgniter 4 Shield生成访问令牌时的"Call to a member function generateAccessToken() on null"错误

错误原因

auth()->user()返回null,说明访问/access/token路由时当前用户未通过认证。Shield的auth()->user()仅在用户已登录(通过Session或Token认证)时才会返回有效的用户实例,直接浏览器访问该路由时没有携带登录会话,因此触发错误。

正确实现方式

1. 给路由添加认证保护

首先要确保只有已登录用户才能访问该路由,使用Shield内置的auth过滤器,同时处理token_name的默认值、规范响应格式:

$routes->get('/access/token', static function() {
    $tokenName = service('request')->getVar('token_name') ?? 'default-token';
    $token = auth()->user()->generateAccessToken($tokenName);

    return service('response')->setJSON(['token' => $token->raw_token]);
})->filter('auth');

如果需要更明确的错误提示,也可以手动校验认证状态:

$routes->get('/access/token', static function() {
    if (!auth()->check()) {
        return service('response')
            ->setJSON(['error' => '未认证用户无法生成访问令牌'])
            ->setStatusCode(401);
    }

    $tokenName = service('request')->getVar('token_name') ?? 'default-token';
    $token = auth()->user()->generateAccessToken($tokenName);

    return service('response')->setJSON(['token' => $token->raw_token]);
})->filter('auth');

2. 验证用户模型的AccessToken特性

检查你的App\Models\User模型是否启用了Shield的HasAccessTokens trait,这是生成令牌的必要前提:

<?php

namespace App\Models;

use CodeIgniter\Shield\Models\User as ShieldUser;
use CodeIgniter\Shield\Models\Traits\HasAccessTokens;

class User extends ShieldUser
{
    use HasAccessTokens;

    // 其他模型代码
}

3. 正确访问路由的方式

  • 先通过登录页面/接口完成登录,确保会话有效
  • 访问路由时可携带自定义令牌名称:https://example.com/access/token?token_name=my-app-token,不传则使用代码中设置的default-token作为名称

额外注意

  • 避免直接用json_encode返回响应,CodeIgniter的setJSON()方法会自动设置正确的Content-Type响应头,更符合API规范
  • 如果需要通过API Token而非Session认证访问该路由,需在请求头中携带Authorization: Bearer {已有的有效令牌},此时auth()->user()也能正确返回用户实例

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 11:00:42