前提
Laravel8でSanctumを用いた認証機能を実装中です。
フロントでVue.jsを用いており、そこからaxiosで認証情報をjson形式でリクエストに追加して、Laravel側にPOSTメソッドを送っています。
リクエストはLaravelのルーティング機能を介してコントローラに渡され、App\Models\UserがSanctumのHashApiTokensのトレイトを使用することでアクセストークンを発行する処理を実装しましたが、
Userで参照しているはずのHashApiTokensを使用できない状況です。
ググって出てきたものは全て試してみましたが、解決していない状況です。
実現したいこと
- User内でHashApiTokensの参照
- コントローラー内でHashApiTokensを用いたトークンの発行
環境
- エディタPhpStorm、VSコード
##docker-composeを用いて以下のイメージで作成したコンテナを使用
php_8.0
- Laravel_8
- npm
- composer_2.0.8
nginx_1.19
mysql
発生している問題・エラーメッセージ
l. App\Models\UserでLaravel\Sanctum\HashApiTokensが参照されない。
エラーメッセージ_Chromeの検証機能でリクエストを送るとコンソールから以下のメッセージが表示される Error! HTTP Status: Error: Request failed with status code 500 app.js:54967 Error! HTTP Status: Error: Request failed with status code 500 {message: "Trait "Laravel\Sanctum\HashApiTokens" not found", exception: "Symfony\Component\ErrorHandler\Error\FatalError", file: "/var/www/html/laravel-vue-app/app/Models/User.php", line: 10, trace: Array(0)} exception: "Symfony\Component\ErrorHandler\Error\FatalError" file: "/var/www/html/laravel-vue-app/app/Models/User.php" line: 10 message: "Trait "Laravel\Sanctum\HashApiTokens" not found"
該当のソースコード
php
1ソースコード_App\Models\Users 2<?php 3 4namespace App\Models; 5use Illuminate\Contracts\Auth\MustVerifyEmail; 6use Illuminate\Database\Eloquent\Factories\HasFactory; 7use Illuminate\Foundation\Auth\User as Authenticatable; 8use Illuminate\Notifications\Notifiable; 9use Laravel\Sanctum\HashApiTokens; //ここが参照されない 10 11class User extends Authenticatable 12{ 13 use HashApiTokens; 14 use HasFactory, Notifiable; 15 16 /** 17 * The attributes that are mass assignable. 18 * 19 * @var array 20 */ 21 protected $fillable = [ 22 'name', 23 'email', 24 'password', 25 ]; 26 27 /** 28 * The attributes that should be hidden for arrays. 29 * 30 * @var array 31 */ 32 protected $hidden = [ 33 'password', 34 'remember_token', 35 ]; 36 37 /** 38 * The attributes that should be cast to native types. 39 * 40 * @var array 41 */ 42 protected $casts = [ 43 'email_verified_at' => 'datetime', 44 ]; 45} 46
php
1HashApiTokens 2<?php 3 4namespace Laravel\Sanctum; 5 6use Illuminate\Support\Str; 7 8trait HasApiTokens 9{ 10 /** 11 * The access token the user is using for the current request. 12 * 13 * @var \Laravel\Sanctum\Contracts\HasAbilities 14 */ 15 protected $accessToken; 16 17 /** 18 * Get the access tokens that belong to model. 19 * 20 * @return \Illuminate\Database\Eloquent\Relations\MorphMany 21 */ 22 public function tokens() 23 { 24 return $this->morphMany(Sanctum::$personalAccessTokenModel, 'tokenable'); 25 } 26 27 /** 28 * Determine if the current API token has a given scope. 29 * 30 * @param string $ability 31 * @return bool 32 */ 33 public function tokenCan(string $ability) 34 { 35 return $this->accessToken ? $this->accessToken->can($ability) : false; 36 } 37 38 /** 39 * Create a new personal access token for the user. 40 * 41 * @param string $name 42 * @param array $abilities 43 * @return \Laravel\Sanctum\NewAccessToken 44 */ 45 public function createToken(string $name, array $abilities = ['*'])//これをUserの関数としてコントローラーから呼び出したい 46 { 47 $token = $this->tokens()->create([ 48 'name' => $name, 49 'token' => hash('sha256', $plainTextToken = Str::random(40)), 50 'abilities' => $abilities, 51 ]); 52 53 return new NewAccessToken($token, $token->id.'|'.$plainTextToken); 54 } 55 56 /** 57 * Get the access token currently associated with the user. 58 * 59 * @return \Laravel\Sanctum\Contracts\HasAbilities 60 */ 61 public function currentAccessToken() 62 { 63 return $this->accessToken; 64 } 65 66 /** 67 * Set the current access token for the user. 68 * 69 * @param \Laravel\Sanctum\Contracts\HasAbilities $accessToken 70 * @return $this 71 */ 72 public function withAccessToken($accessToken) 73 { 74 $this->accessToken = $accessToken; 75 76 return $this; 77 } 78}
php
1ソースコード_コントローラー 2<?php 3 4namespace App\Http\Controllers\Auth\Api; 5 6use App\Http\Controllers\Controller; 7use App\Models\User; 8use Illuminate\Foundation\Auth\AuthenticatesUsers; 9use Illuminate\Http\Request; 10use Illuminate\Support\Facades\Hash; 11use Illuminate\Validation\ValidationException; 12 13class LoginController extends Controller 14{ 15 use AuthenticatesUsers; 16 17 /** 18 * Handle a login request to the application. 19 * 20 * @param \Illuminate\Http\Request $request 21 * @return \Illuminate\Http\Response|\Illuminate\Http\JsonResponse 22 * 23 * @throws \Illuminate\Validation\ValidationException 24 */ 25 public function login(Request $request) 26 { 27 // バリデーション 28 $this->validateLogin($request); 29 30 // ユーザーの取得 31 $user = User::where('email', $request->email)->first(); 32 33 // 取得できない場合、パスワードが不一致の場合エラー 34 if (!$user || !Hash::check($request->password, $user->password)) { 35 throw ValidationException::withMessages([ 36 'email' => [__('failed')], 37 ]); 38 } 39 40 // tokenの作成 41 $token = $user->createToken($request->device_name)->plainTextToken;//ここでUserにHashApiTokensのトレイトを使用してもらいたいが、Userが参照しているHashApiTokensが参照されない。 42 43 return response()->json(['token' => $token, 'user' => $user], 200); 44 } 45 46 /** 47 * Validate the user login request. 48 * 49 * @param \Illuminate\Http\Request $request 50 * @return void 51 * 52 * @throws \Illuminate\Validation\ValidationException 53 */ 54 protected function validateLogin(Request $request) 55 { 56 // オーバーライドして、デバイス名を必須化しています 57 $request->validate([ 58 $this->username() => 'required|string', 59 'password' => 'required|string', 60 //'email' => 'required', 61 'device_name' => 'required' 62 ]); 63 } 64 65 66 /** 67 * Handle a logout request to the application. 68 * 69 * @param \Illuminate\Http\Request $request 70 * @return \Illuminate\Http\Response|\Illuminate\Http\JsonResponse 71 */ 72 public function logout(Request $request) 73 { 74 $user = $request->user(); 75 76 // tokenの削除 77 $user->tokens()->delete(); 78 79 return response()->json(['message' => 'logouted']); 80 } 81}
試したこと
docker-compose exec でプロジェクトのディレクトリに入り以下を実行
- composer require laravel/sanctum
- php artisan vendor:publish --provider="Laravel\Sanctum\SanctumServiceProvider"
- composer dump-autoload
- php artisan cache:clear
- php artisan config:clear
- php artisan config:cache
- php artisan route:clear
- php artisan view:clear
- php artisan clear-compiled
- php artisan optimize
- rm -f bootstrap/cache/config.ph
その他試したこと
- dockerコンテナの再起動
- ブラウザでキャッシュの削除
- autoload_classmap.phpでエイリアスの確認。
- 一回諦めてちゃんと寝る
補足情報(FW/ツールの
- autoload_classmap.phpでHashApiTokensは以下のようになっており、実際のディレクトリの情報と変わりない(当たり前ですが)ので単純なタイプミスなどでは無いかと思います。
php
1'Laravel\Sanctum\HasApiTokens' => $vendorDir . '/laravel/sanctum/src/HasApiTokens.php',
- Laravel8でUserのディレクトリが変わったことが関係あったりするのでしょうか。。。?
- もう丸一日以上ためしていて自分じゃ限界です。
回答2件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2021/01/02 11:18
2021/01/02 11:31
2021/01/02 11:41