【Laravel】ユーザーログイン済みのみ実行できるAPIの作成

えび

LaravelのAPI作成で、ログイン済みユーザーのみ実行できるようにした手順メモ

1. usersテーブルにapi_tokenカラムを追加

  • migration作成
php artisan make:migration add_api_token_to_users_table
  • migration実装
<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
use App\Models\User;
use Illuminate\Support\Str;

class AddApiTokenToUsersTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::table('users', function (Blueprint $table) {
            $table->string('api_token', 80)->after('password')->unique()->nullable()->default(null);
        });

        // 既存登録ユーザーにapi_tokenを登録
        User::all()->each (function(User $user) {
            $user->update(['api_token' => Str::random(60)]);
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::table('users', function (Blueprint $table) {
            $table->dropColumn('api_token');
        });
    }
}

まだ一度もmigrationを実行していない場合は、
既存のusersテーブル作成用migrationにapi_tokenカラムを足すだけでOK

2. apiルーティング追加

  • routes/api.php
Route::middleware('auth:api')->group(function () {
    Route::post('/user/update', 'UserController@update');
});

デフォルトで用意されているauth:apiミドルウェアを指定するだけで、
api_tokenをパラメータに指定しないと弾いてくれるようになる

これでクエリにて有効なapi_tokenを指定した場合のみ実行可能なAPIが出来上がる

/api/user/update?api_token={{ auth()->user()->api_token }}

3. APIで呼び出すController実装

  • UserController.php
<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

class UserController extends Controller
{
    /**
     * @param Request $request
     * @return \Illuminate\Http\JsonResponse
     */
    public function update(Request $request)
    {
        $request->user()->update([
            'name' => $request->introduction
        ]);

        return response()->json(['status' => 'ok']);
    }
}

api:authルーティングの場合、
$request->user()ログイン済みのユーザーが入ってるのでそれを利用する

例えばメールアドレスを取得したい場合は
$request->user()->email のように取得できる

4. 呼び出してみる

  • routes/web.php
Route::view('/user-update-form', 'user-update-form');
  • UserEditForm.vue
<template>
  <div class="user-form">
    <label for="introduction">自己紹介</label>
    <textarea id="introduction" @input="onInput()" v-model="introduction">{{ introduction }}</textarea>
  </div>
</template>

<script>
export default {
  props: {
    token: {
      type: String,
    },
  },
  data () {
    return {
      introduction: 'こんにちは!こんにちは!',
    }
  },
  methods: {
    onInput () {
      let formData = new FormData()
      formData.append('introduction', this.introduction)

      fetch(`/api/user/update?api_token=${this.token}`, {
        method: 'POST',
        body: formData,
      }).then(function (response) {
        return response.clone().json()
      }).then(function (json) {
        if (json.status === 'ok') {
          //
        }
      }).catch((error) => {
        console.error('Error:', error)
      })
    },
  },
}
</script>
  • resources/js/app.js
// 追加
Vue.component('UserUpdateForm', require('./components/UserUpdateForm.vue').default);
  • resources/views/user-update-form.blade.php
@extends('layouts.app')

@section('content')
    <user-update-form
        token="{{ auth()->user()->api_token }}"
    ></user-update-form>
@endsection

これで、Vueからユーザー情報更新APIを呼び出して更新できるようになった