Laravel 6:调用未定义的方法App \\ User :: createToken()

时间:2019-10-18 02:42:31

标签: php laravel eloquent laravel-passport laravel-authentication

我正尝试通过以下方式生成令牌以验证Controller中的用户:

namespace App\Http\Controllers\API;
use Illuminate\Foundation\Auth\AuthenticatesUsers;
use Illuminate\Http\Request;

use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\Auth;
use App\Models\User;

class AuthController extends Controller
{
    public function login()
    {
        if (Auth::attempt(['email' => request('email'), 'password' => request('password')])) {
            $user = Auth::user();


            $success['token'] = $user->createToken('myApp')->accessToken;
            dd($success['token']);

        }
    }

当前,我只是想打印出令牌。这是我的用户模型:

<?php

namespace App\Models;

use Illuminate\Notifications\Notifiable;
//use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Support\Facades\Hash;
use Laravel\Passport\HasApiTokens;

class User extends Authenticatable
{
    use HasApiTokens, Notifiable;

    const USER_FIRST_NAME_FIELD        = "first_name";
    const USER_LAST_NAME_FIELD         = "last_name";
    const USER_PREFERRED_NAME_FIELD    = "preferred_name";
    const USER_EMAIL_FIELD             = "email";
    const USER_EMAIL_VERIFIED_AT_FIELD = "email_verified_at";
    const USER_PASSWORD_FIELD          = "password";
    const USER_REMEMBER_TOKEN_FIELD    = "remember_token";
    const USER_RECEIVE_NEWSLETTER_FIELD= "receive_newsletter";
    const USER_ACTIVE_FIELD            = "active";

    /**
     * The attributes that are mass assignable.
     *
     * @var array
     */
    protected $fillable = [
        self::USER_FIRST_NAME_FIELD, 
        self::USER_LAST_NAME_FIELD,
        self::USER_PREFERRED_NAME_FIELD,
        self::USER_EMAIL_FIELD,
        self::USER_PASSWORD_FIELD,
        self::USER_RECEIVE_NEWSLETTER_FIELD,
        self::USER_ACTIVE_FIELD,
    ];

    /**
     * The attributes that should be hidden for arrays.
     *
     * @var array
     */
    protected $hidden = [
        self::USER_PASSWORD_FIELD,
        self::USER_REMEMBER_TOKEN_FIELD
    ];

    /**
     * Automatically creates password hash when password is submitted
     *
     * @param string $password
     * @return void
     */
    public function setPasswordAttribute(string $password) : void
    {
        $this->attributes['password'] = Hash::make($password);    
    }
}

如您所见,我正在使用HasApiTokens, Notifiable特征,但是我从控制器收到错误消息:

  

调用未定义的方法App \ User :: createToken()

护照已正确安装和配置。

这有点奇怪:

注册用户时(我正在使用单独的控制器,也正在使用服务),令牌创建成功:

这是我的控制器:

<?php

namespace App\Http\Controllers\API;

use App\Services\UserService;
use Illuminate\Http\JsonResponse;
use App\Http\Controllers\Controller;
use App\Http\Requests\RegisterUserRequest;


class UserController extends Controller 
{
    private $user;

    public function __construct(UserService $user)
    {
        $this->user = $user;
    }

    public function store(RegisterUserRequest $request) : JsonResponse
    {
        // TODO: verify message on error

        $user = $this->user->register($request->validated());
        $token = $user->createToken('MyApp')->accessToken;
        dd($token);

        return response()->json(['status' => 201, 'user_id' => $user->id]);
    }

}

这是我的服务

<?php

namespace App\Services;

use App\Models\User;
use App\Services\BaseServiceInterface;

class UserService implements BaseServiceInterface
{

    public function register(array $formValues) : User
    {
        // 'terms and conditions' should not be saved into the db, hence it's removed
        unset($formValues['terms_conditions']);
        return User::create($formValues);
    }

}

这又是我的模特:

<?php

namespace App\Models;

use Illuminate\Notifications\Notifiable;
//use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Support\Facades\Hash;
use Laravel\Passport\HasApiTokens;

class User extends Authenticatable
{
    use HasApiTokens, Notifiable;

    const USER_FIRST_NAME_FIELD        = "first_name";
    const USER_LAST_NAME_FIELD         = "last_name";
    const USER_PREFERRED_NAME_FIELD    = "preferred_name";
    const USER_EMAIL_FIELD             = "email";
    const USER_EMAIL_VERIFIED_AT_FIELD = "email_verified_at";
    const USER_PASSWORD_FIELD          = "password";
    const USER_REMEMBER_TOKEN_FIELD    = "remember_token";
    const USER_RECEIVE_NEWSLETTER_FIELD= "receive_newsletter";
    const USER_ACTIVE_FIELD            = "active";

    /**
     * The attributes that are mass assignable.
     *
     * @var array
     */
    protected $fillable = [
        self::USER_FIRST_NAME_FIELD, 
        self::USER_LAST_NAME_FIELD,
        self::USER_PREFERRED_NAME_FIELD,
        self::USER_EMAIL_FIELD,
        self::USER_PASSWORD_FIELD,
        self::USER_RECEIVE_NEWSLETTER_FIELD,
        self::USER_ACTIVE_FIELD,
    ];

    /**
     * The attributes that should be hidden for arrays.
     *
     * @var array
     */
    protected $hidden = [
        self::USER_PASSWORD_FIELD,
        self::USER_REMEMBER_TOKEN_FIELD
    ];

正如我告诉您的那样,在创建用户时,令牌已正确生成。

我会说Auth::user()不是直接调用我的模型,但我不确定这是怎么回事。

知道为什么吗? 谢谢

4 个答案:

答案 0 :(得分:2)

由于后卫返回了错误的User模型App\User,因此您应该检查auth配置'config / auth.php'。在providers数组中,将通常使用users模型的任何提供程序(通常为App\User)调整为App\Models\User

'providers' => [
    'users' => [
        'driver' => 'eloquent',
        // 'model' => App\User::class,
        'model' => App\Models\User::class,
    ],
    ...
],

答案 1 :(得分:2)

就我而言,我错过了使用 Trait HasApiTokens 这就是 Laravel 无法创建令牌的原因。

只需打开 User.php

在名字空间包含之后

use Laravel\Passport\HasApiTokens;

然后在课堂上

use HasApiTokens

请注意:我使用的是 laravel 7。

答案 2 :(得分:1)

您可以通过在构造方法中调用auth.basic中间件来为您执行身份验证:

public function __construct()
    {
        $this->middleware('auth.basic'); 
    }

然后为当前经过身份验证的用户生成访问令牌,并返回用户信息以及访问令牌:

public function login()
    {
        $Accesstoken = Auth::user()->createToken('Access Token')->accessToken;

        return Response(['User' => Auth::user(), 'Access Token' => $Accesstoken]);
    }

现在控制器将如下所示:

    <?php


namespace App\Http\Controllers\API;

use App\Models\User;
use Illuminate\Support\Facades\Auth;
use App\Http\Controllers\API\BaseController;

class AuthController extends BaseController
{
        /**
         * Instantiate a new controller instance.
         *
         * @return void
         */
        public function __construct()
        {
            $this->middleware('auth.basic'); 
        }

        public function login()
        {
            $Accesstoken = Auth::user()->createToken('Access Token')->accessToken;

            return Response(['User' => Auth::user(), 'Access Token' => $Accesstoken]);
        }
    }

答案 3 :(得分:0)

所以,这不是正确的方法,但目前正在起作用:

<?php

namespace App\Http\Controllers\API;

use App\Models\User;
use Illuminate\Support\Facades\Auth;
use App\Http\Controllers\API\BaseController;

class AuthController extends BaseController
{
    public function login()
    {
        if (Auth::attempt(['email' => request('email'), 'password' => request('password')])) {
            $authenticated_user = \Auth::user();
            $user = User::find($authenticated_user->id);
            dd($user->createToken('myApp')->accessToken);
        }

        dd('here');
    }
}

现在我正在看到令牌。

我想以正确的方式来做,所以如果有人可以帮助我,我仍然感激不尽。 谢谢