lg23

668 经验值

<?php
namespace App\Api\Controllers\V1;

use App\Api\Controllers\BaseController;
use Illuminate\Http\Request;
use App\Service\OrderService;
use App\Api\Transformers\OrderTransformer;
use App\Api\Controllers\V1\AuthController;
use Dingo\Api\Routing\Helpers;

class OrderController extends BaseController
{
    use Helpers;
    public function show(Request $request, $type)
    {   
        $user = $this->user();
        return $user;
        $order = self::$orderService
                     ->apiGetOrderList($uid, $type);

        // 不存在 调用dingo 的 response 方法返回错误信息
        if(!$order) {
            return $this->response->errorNotFound('order not found');
        }

        return $this->response->item($order, new OrderTransformer());
    }

}

我在这里 use 后,还是报错

"message": "Call to undefined method Closure::authenticate()",
  "status_code": 500,
  "debug": {
    "line": 82,
    "file": "/vagrant/tb100/admin/vendor/dingo/api/src/Auth/Auth.php",
    "class": "Symfony\\Component\\Debug\\Exception\\FatalThrowableError",

我不知道为什么这个方法是正常调用的,我先用这个方法
$user = JWTAuth::parseToken()->authenticate();

在 use Dingo\Api\Routing\Helpers; 这个里面有一个方法

/**
     * Get the authenticated user.
     * 获取认证用户
     * @return mixed
     */
    protected function user()
    {
        return app(Auth::class)->user();
    }

我想调用这个方法应该如何调用呢?
我目前的调用方式
创建基础控制器

<?php
namespace App\Api\Controllers;

use Dingo\Api\Routing\Helpers;
use App\Http\Controllers\Controller;

class BaseController extends Controller
{
    // 接口帮助调用
    use Helpers;
}

其它控制器继承基础控制器

<?php
namespace App\Api\Controllers\V1;

use App\Api\Controllers\BaseController;
use Illuminate\Http\Request;
use App\Service\OrderService;
use App\Api\Transformers\OrderTransformer;
use App\Api\Controllers\V1\AuthController;


class OrderController extends BaseController
{
    public function show(Request $request, $type)
    {   
        $user = $this->user();
        return $user;
        $order = self::$orderService
                     ->apiGetOrderList($uid, $type);

        // 不存在 调用dingo 的 response 方法返回错误信息
        if(!$order) {
            return $this->response->errorNotFound('order not found');
        }

        return $this->response->item($order, new OrderTransformer());
    }

}

在上面的调用过程中,出现以下报错:
"message": "Call to undefined method Closure::authenticate()",
"status_code": 500,
"debug": {

"line": 82,
"file": "/vagrant/tb100/admin/vendor/dingo/api/src/Auth/Auth.php",
"class": "Symfony\\Component\\Debug\\Exception\\FatalThrowableError",

初步猜测是同 Auth 有关,这里具体应该如何配置,还请求指点!

问题我解决了,我在数据库中增加了一个 id 字段,这个问题让我纠结了好几天,谢谢了

Column not found: 1054 Unknown column 'data_users.id' in 'where clause' (SQL: select * from data_users where data_users.id is null limit 1)"

对了,上次就是有这个报错,我才使用了自定义主键 protected $primaryKey = 'uid';
如果不使用自定义主键,这里会报上面的错,使用可能找不到用户,那我应该怎么处理呢?

我忘了当时是什么情况,大概记得是sql出错,说是到不到 id,因为我表中没有id,所以在user.php里设置了自定义主键,晚点回来,我试一下。谢谢群主

问题解决了,是我换JWT版本引起 的。需要更新composer 后再安装JWT

登录正常,token 获取正常 但访问 user/me 路由(控制器: getAuthenticatedUser)时提示:
"user_not_found" 或 token_invalid
尝试过在 app\http\AuthController.php 中指定 protected $username = 'mobile';
在 user.php 中添加 public function getAuthName() 但问题依旧存在
控制器代码

<?php
namespace App\Api\Controllers\V1;

use Illuminate\Http\Request;
use App\Api\Controllers\BaseController;
use Tymon\JWTAuth\Exceptions\JWTException;
use JWTAuth;
use App\Service\UserService;
use Carbon\Carbon;

class AuthController extends BaseController
{
     private static $userService;
     protected $username = 'tel';

     public function __construct(UserService $userService)
     {
         self::$userService = $userService;
     }

    /**
     * 验证用户  获取token
     * @param Request $request
     * @return \Illuminate\Http\JsonResponse
     */
    public function authenticate(Request $request)
    {
        $payload = [
            'tel' => $request->get('phone'),
            'password' => $request->get('passw'),
            'status' => 0
        ];

        try {
            // attempt 尝试验证凭据并为用户创建令牌
            if (! $token = JWTAuth::attempt($payload)) {
                // 返回无效令牌
                return response()->json(['error' => 'invalid_credentials'], 401);
              }
        } catch (JWTException $e) {
            // 尝试创建 token 令牌时出错
            return response()->json(['error' => 'could_not_create_token'], 500);
        }

        $result['data'] = [
            'token' => $token,
            'expired_at' => Carbon::now()->addMinutes(config('jwt.ttl'))->toDateTimeString(),
            'refresh_expired_at' => Carbon::now()->addMinutes(config('jwt.refresh_ttl'))->toDateTimeString(),
            'type' => true,
        ];

        return $this->response->array($result)->setStatusCode(201);
        
    }


    /**
     * 根据 token 获取用户信息
     * 
     */
    public function getAuthenticatedUser()
    {
       try {// parseToken 解析令牌请求来源
           if (! $user = JWTAuth::parseToken()->authenticate()) {
               return response()->json(['user_not_found'], 404);
           }
       } catch (TokenExpiredException $e) {
           return response()->json(['token_expired'], $e->getStatusCode());
       } catch (TokenInvalidException $e) {
           return response()->json(['token_invalid'], $e->getStatusCode());
       } catch (JWTException $e) {
           return response()->json(['token_absent'], $e->getStatusCode());
       }

       // token 有效,找到用户
       return response()->json(compact('user'));
    }

}

路由代码:
$api = app('Dingo\Api\Routing\Router');

$api->version('v1', function ($api) {
    $api->group(['namespace' => 'App\Api\Controllers\V1', 'middleware' => 'cors'], function ($api) {

        $api->POST('/register', [
            'limit' => 50, 
            'expires' => 5,
            'as' => 'register.register',
            'uses' => 'AuthController@register',
        ]);
        // 登录
        $api->POST('/login', [
            'limit' => 50, 
            'expires' => 5,
            'as' => 'login.authenticate',
            'uses' => 'AuthController@authenticate',
        ]);

        // 通过 jwt.auth 中间件限制未登录权限
        $api->group(['middleware' => 'jwt.refresh'], function ($api) {
            $api->get('user/me', 'AuthController@getAuthenticatedUser');

        });

    });
    
})

user.php 代码 
<?php
namespace App\Model;

use Illuminate\Notifications\Notifiable;
use Illuminate\Foundation\Auth\User as Authenticatable;

class User extends Authenticatable
{   
    // JWT 中有指定验证的字段,使用 Notifiable 来修改这些指定
    use Notifiable;
    
    /**
     * 白名单 $fillable 属性指定了哪些字段支持批量赋值
     * @var array
     */
    protected $fillable = ['uid', 'username', 'tel', 'password', 'pic', 'status', 'addtime'];
    /**
     * 模型所使用的数据库表
     * @var string
     */
    protected $table = 'data_users';
    /** 
     * 自定义主键
     */
    protected $primaryKey = 'uid';

    /**
     * 关闭 递增
     */
    public $incrementing = false;
    /**
     * 关闭 创建时间 与 更新时间的自动维护
     */
    public $timestamps = false;

    /** 
     * 转换成数组或 JSON 时隐藏属性
     * 查询用户的时候,不暴露密码
     * @var array 
     */  
    protected $hidden = ['password', 'remember_token'];

    /**
     * jwt 默认密码字段 password 
     * 修改密码字段
     */
    public function getAuthPassword()
    {
        return $this->password;
    }

    /**
     * 修改 jwt 默认用户名字段 
     */
    public function getAuthName()
    {
        return $this->tel;
    }

}

app\config 目录下 auth.php 配置

<?php

return [

    'defaults' => [
        'guard' => 'web',
        'passwords' => 'users',
    ],

    'guards' => [
        'web' => [
            'driver' => 'session',
            'provider' => 'users',
        ],

        'api' => [
            'driver' => 'jwt',// 默认token
            'provider' => 'users',
        ],
    ],

    // 这里默认关联模型(eloquent) App\User
    'providers' => [
        'users' => [
            'driver' => 'eloquent',
            'model' => App\Model\User::class,
            'table' => 'data_users',
        ],

        'users' => [
            'driver' => 'database',
            'table' => 'users',
        ],
    ],

    'passwords' => [
        'users' => [
            'provider' => 'users',
            'table' => 'password_resets',
            'expire' => 60,
        ],
    ],

];

JWT.php文件配置内容:

<?php

return [

    'secret' => env('JWT_SECRET', 'ZLTVDUQ6lAEayTvgIUTIcRMd833zmNb4'),

    'ttl' => 60,

    'refresh_ttl' => 20160,

    'algo' => 'HS256',

    'user' => 'App\Model\User',

    'identifier' => 'id',

    'required_claims' => ['iss', 'iat', 'exp', 'nbf', 'sub', 'jti'],

    'blacklist_enabled' => env('JWT_BLACKLIST_ENABLED', true),

    'providers' => [

        'user' => 'Tymon\JWTAuth\Providers\User\EloquentUserAdapter',

        'jwt' => 'Tymon\JWTAuth\Providers\JWT\NamshiAdapter',

        'auth' => 'Tymon\JWTAuth\Providers\Auth\IlluminateAuthAdapter',


        'storage' => 'Tymon\JWTAuth\Providers\Storage\IlluminateCacheAdapter',
    ],

];

app\model 目录下的user.php

<?php
namespace App\Model;

use Illuminate\Notifications\Notifiable;
use Illuminate\Foundation\Auth\User as Authenticatable;

class User extends Authenticatable
{    
    // JWT 中有指定验证的字段,使用 Notifiable 来修改这些指定
    use Notifiable;
    
    /**
     * 白名单 $fillable 属性指定了哪些字段支持批量赋值
     * @var array
     */
    protected $fillable = ['uid', 'username', 'tel', 'password', 'pic', 'status', 'addtime'];
    /**
     * 模型所使用的数据库表
     * @var string
     */
    protected $table = 'data_users';
    /** 
     * 自定义主键
     */
    protected $primaryKey = 'uid';

    /**
     * 关闭 递增
     */
    public $incrementing = false;
    /**
     * 关闭 创建时间 与 更新时间的自动维护
     */
    public $timestamps = false;

    /** 
     * 转换成数组或 JSON 时隐藏属性
     * 查询用户的时候,不暴露密码
     * @var array 
     */  
    protected $hidden = ['password', 'remember_token'];

    /**
     * jwt 默认密码字段 password 
     * 修改密码字段
     */
    public function getAuthPassword()
    {
        return $this->password;
    }

    /**
     * 获取用户的唯一标识符
     * jwt 需要实现的方法
     */
    // public function getJWTIdentifier()
    // {
    //     return $this->getKey();// 模型的方法
    // }

    // jwt 需要实现的方法
    // public function getJWTCustomClaims()
    // {
    //     return [];
    // }

    /**
     * 用户-订单一对多关联
     */
    public function hasUserOrder()
    {
        return $this->hasMany('App\Model\Order', 'uid', 'uid');
    }

    /**
     * 用户-购物车一对多关联
     */
    public function hasUserCart()
    {
        return $this->hasMany('App\Model\Cart', 'uid', 'uid');
    }

}

目前在我的 store 层,无法获取到数据,用户查询返回为空(用户真实存在)public static function apiGetUser($param)

    public static function apiGetUser($param)
    {
        // return Auth::where($param)->first();
        return \DB::table('data_users')
                ->where($param)->first();
    }

两种方法,均无法从 data_users 表中读取到数据,怀疑 user.php 的接口问题。新建一个 Auth.php 模型

<?php
namespace App\Model;

use Illuminate\Database\Eloquent\Model;

class Auth extends Model
{        
    /**
     * 白名单 $fillable 属性指定了哪些字段支持批量赋值
     * @var array
     */
    protected $fillable = ['uid', 'username', 'tel', 'password', 'pic', 'status', 'addtime'];
    /**
     * 模型所使用的数据库表
     * @var string
     */
    protected $table = 'data_users';
    /** 
     * 自定义主键
     */
    protected $primaryKey = 'uid';

    /**
     * 关闭 递增
     */
    public $incrementing = false;
    /**
     * 关闭 创建时间 与 更新时间的自动维护
     */
    public $timestamps = false;

    /** 
     * 转换成数组或 JSON 时隐藏属性
     * 查询用户的时候,不暴露密码
     * @var array 
     */  
    protected $hidden = ['password', 'remember_token'];

    /**
     * 用户-订单一对多关联
     */
    public function hasUserOrder()
    {
        return $this->hasMany('App\Model\Order', 'uid', 'uid');
    }

    /**
     * 用户-购物车一对多关联
     */
    public function hasUserCart()
    {
        return $this->hasMany('App\Model\Cart', 'uid', 'uid');
    }

}

但问题依然是没有从数据库获取到数据,再这里向各位有相同经历或是了解这问题的同学请教,谢谢!

AuthController.php 实现登录
···

<?php
namespace App\Api\Controllers\V1;

use Illuminate\Http\Request;
use App\Api\Controllers\BaseController;
use Tymon\JWTAuth\Exceptions\JWTException;
use JWTAuth;
use App\Service\UsersService;
use Carbon\Carbon;

class AuthController extends BaseController
{
     private static $usersService;

     public function __construct(UsersService $usersService)
     {
         self::$usersService = $usersService;
     }

    /**
  • 验证用户 获取token

  • @param Request $request

  • @return \Illuminate\Http\JsonResponse
    */

        public function authenticate(Request $request)
        {

    $payload = [

       'tel' => $request->get('phone'),
       'password' => $request->get('passw'),
       'status' => 0

    ];

    try {

       // attempt 尝试验证凭据并为用户创建令牌
       if (! $token = JWTAuth::attempt($payload)) {
           // 返回无效令牌
           return response()->json(['error' => 'invalid_credentials'], 401);
        }

    } catch (JWTException $e) {

      // 尝试创建 token 令牌时出错
       return response()->json(['error' => 'could_not_create_token'], 500);

    }

    // 返回 token 令牌 compact函数创建一个由参数所带变量组成的数组
    return response()->json(compact('token'));

    // $result['data'] = [
    // 'token' => $token,
    // 'expired_at' => Carbon::now()->addMinutes(config('jwt.ttl'))->toDateTimeString(),
    // 'refresh_expired_at' => Carbon::now()->addMinutes(config('jwt.refresh_ttl'))->toDateTimeString(),
    // 'type' => true,
    // ];

    // return $this->response->array($result)->setStatusCode(201);

        }
    }
    

···

群主,在上登录认证成功返回token时,有没有什么方法一并返回用户的 uid

主要是不知道应该贴哪些代码

是的,我的认证字段是 tel 和 password,
如果JWT默认了这个认证字段,我应该怎么修改这个认证字段呢?