ottott
@ottott (kouhei)

Are you sure you want to delete the question?

Leaving a resolved question undeleted may help others!

nuxt.jsとlaravelを使用したログイン機能について

ここに解決したい内容を記載してください。


http://localhost:3000/register で入力した名前、メールアドレス、パスワードを保存し使えるようにしたいです。

発生している問題・エラー

http://localhost:3000/register 
で名前、メールアドレス、パスワードを登録しようとすると、まだ登録していないのにメールアドレスがすでに登録されています。と表示されます。
そのため、phpmyadminで使用しているデータベースのテーブルの中身を確認しましたが一つも値は入っていません。
$ php artisan migrateはうまくできています。
それで、検証でconsoleを見るとこのようなエラーになります。

500 (Internal Server Error)

該当するソースコード

index.vue
<template>
  <div class="container">
    <p v-if="$auth.loggedIn">Name:{{ $auth.user.name }}</p>
  </div>
</template>
default.vue
<template>
  <div>
    <CommonHeader />
    <Nuxt />
  </div>
</template>
CommonHeader.vue
<template>
  <header>
    <h1 class="title">{{ $route.name }}</h1>
    <nav class="nav">
      <ul class="menu-group">
        <li class="menu-item" v-if="!$auth.loggedIn">
          <NuxtLink to="/register">Register</NuxtLink>
        </li>
        <li class="menu-item" v-if="!$auth.loggedIn">
          <NuxtLink to="/login">Login</NuxtLink>
        </li>
        <li class="menu-item" v-else>
          <a @click="logout">Logout</a>
        </li>
      </ul>
    </nav>
  </header>
</template>

<script>
export default {
  methods: {
    async logout() {
      try {
        await this.$auth.logout();
        this.$router.push("/login");
      } catch (error) {
        console.log(error);
      }
    },
  },
};
</script>

<style scoped>
header {
  display: flex;
  height: 100px;
  padding: 0 50px;
  margin-bottom: 30px;
  background-color: darkgrey;
  align-items: center;
}
.title {
  margin-right: auto;
}
.menu-item {
  list-style: none;
  display: inline-block;
  padding: 10px;
}
.menu-item a {
  color: black;
  text-decoration: none;
  cursor: pointer;
}
</style>

register.vue
<template>
  <form @submit.prevent="register">
    <input type="text" v-model="name" placeholder="name" required />
    <input type="email" v-model="email" placeholder="email" required />
    <input type="password" v-model="password" placeholder="password" required />
    <button type="submit">送信</button>
  </form>
</template>

<script>
export default {
  auth: false,
  data() {
    return {
      name: null,
      email: null,
      password: null,
    };
  },
  methods: {
    async register() {
      try {
        await this.$axios.post("http://localhost:8000/api/auth/register", {
          name: this.name,
          email: this.email,
          password: this.password,
        });
        this.$router.push("/login");
      } catch {
        alert("メールアドレスがすでに登録されています");
      }
    },
  },
};
</script>

login.vue
<template>
  <form @submit.prevent="login">
    <input type="email" v-model="email" placeholder="email" required />
    <input type="password" v-model="password" placeholder="password" required />
    <button type="submit">送信</button>
  </form>
</template>

<script>
export default {
  data() {
    return {
      email: null,
      password: null,
    };
  },
  methods: {
    async login() {
      try {
        await this.$auth.loginWith("laravelJWT", {
          data: {
            email: this.email,
            password: this.password,
          },
        });
        this.$router.push("/");
      } catch {
        alert("メールアドレスまたはパスワードが間違っております");
      }
    },
  },
};
</script>

nuxt.config.js
export default {
  // Disable server-side rendering: https://go.nuxtjs.dev/ssr-mode
  ssr: false,

  // Target: https://go.nuxtjs.dev/config-target
  target: 'static',

  // Global page headers: https://go.nuxtjs.dev/config-head
  head: {
    title: 'jwt-frontend',
    htmlAttrs: {
      lang: 'en'
    },
    meta: [
      { charset: 'utf-8' },
      { name: 'viewport', content: 'width=device-width, initial-scale=1' },
      { hid: 'description', name: 'description', content: '' },
      { name: 'format-detection', content: 'telephone=no' }
    ],
    link: [
      { rel: 'icon', type: 'image/x-icon', href: '/favicon.ico' }
    ]
  },

  // Global CSS: https://go.nuxtjs.dev/config-css
  css: [
  ],

  // Plugins to run before rendering page: https://go.nuxtjs.dev/config-plugins
  plugins: [
  ],

  // Auto import components: https://go.nuxtjs.dev/config-components
  components: true,

  // Modules for dev and build (recommended): https://go.nuxtjs.dev/config-modules
  buildModules: [
    // https://go.nuxtjs.dev/eslint
    '@nuxtjs/eslint-module'
  ],

  // Modules: https://go.nuxtjs.dev/config-modules
  modules: [
    '@nuxtjs/axios',
  //以下の1文を追加
  '@nuxtjs/auth-next'
  ],

  // Axios module configuration: https://go.nuxtjs.dev/config-axios
  axios: {},

  // Build Configuration: https://go.nuxtjs.dev/config-build
  build: {
  },

  auth: {
    strategies: {
      'laravelJWT': {
        provider: 'laravel/jwt',
        url: 'http://localhost:8000',
        token: {
          maxAge: 60 * 60
        },
        refreshToken: {
          maxAge: 20160 * 60
        }
      },
    },
  },

}

.env
APP_NAME=Laravel
APP_ENV=local
APP_KEY=base64:eflcrwRNqAcUScKqiU/wUzGSzyFSKTv2SfdFcH8bc6Y=
APP_DEBUG=true
APP_URL=http://localhost

LOG_CHANNEL=stack
LOG_LEVEL=debug

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=8889
DB_DATABASE=jwt
DB_USERNAME=root
DB_PASSWORD=gyarmex

BROADCAST_DRIVER=log
CACHE_DRIVER=file
FILESYSTEM_DRIVER=local
QUEUE_CONNECTION=sync
SESSION_DRIVER=file
SESSION_LIFETIME=120

MEMCACHED_HOST=127.0.0.1

REDIS_HOST=127.0.0.1
REDIS_PASSWORD=null
REDIS_PORT=6379

MAIL_MAILER=smtp
MAIL_HOST=mailhog
MAIL_PORT=1025
MAIL_USERNAME=null
MAIL_PASSWORD=null
MAIL_ENCRYPTION=null
MAIL_FROM_ADDRESS=null
MAIL_FROM_NAME="${APP_NAME}"

AWS_ACCESS_KEY_ID=
AWS_SECRET_ACCESS_KEY=
AWS_DEFAULT_REGION=us-east-1
AWS_BUCKET=
AWS_USE_PATH_STYLE_ENDPOINT=false

PUSHER_APP_ID=
PUSHER_APP_KEY=
PUSHER_APP_SECRET=
PUSHER_APP_CLUSTER=mt1

MIX_PUSHER_APP_KEY="${PUSHER_APP_KEY}"
MIX_PUSHER_APP_CLUSTER="${PUSHER_APP_CLUSTER}"

User.php
<?php

namespace App\Models;

use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;

//以下の1文を追加
use Tymon\JWTAuth\Contracts\JWTSubject;

//以下の1文を修正
class User extends Authenticatable implements JWTSubject
{
    use HasFactory, Notifiable;

    /**
     * The attributes that are mass assignable.
     *
     * @var array
     */
    protected $fillable = [
        'name',
        'email',
        'password',
    ];

    /**
     * The attributes that should be hidden for arrays.
     *
     * @var array
     */
    protected $hidden = [
        'password',
        'remember_token',
    ];


    /**
     * The attributes that should be cast to native types.
     *
     * @var array
     */
    protected $casts = [
        'email_verified_at' => 'datetime',
    ];

//追加
public function getJWTIdentifier()
{
    return $this->getKey();
}


public function getJWTCustomClaims()
{
    return [];
}
//追加終わり
}

auth.php
<?php

namespace App\Models;

use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;

//以下の1文を追加
use Tymon\JWTAuth\Contracts\JWTSubject;

//以下の1文を修正
class User extends Authenticatable implements JWTSubject
{
    use HasFactory, Notifiable;

    /**
     * The attributes that are mass assignable.
     *
     * @var array
     */
    protected $fillable = [
        'name',
        'email',
        'password',
    ];

    /**
     * The attributes that should be hidden for arrays.
     *
     * @var array
     */
    protected $hidden = [
        'password',
        'remember_token',
    ];


    /**
     * The attributes that should be cast to native types.
     *
     * @var array
     */
    protected $casts = [
        'email_verified_at' => 'datetime',
    ];

//追加
public function getJWTIdentifier()
{
    return $this->getKey();
}


public function getJWTCustomClaims()
{
    return [];
}
//追加終わり
}

api.php
<?php

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Route;
use App\Http\Controllers\AuthController;

Route::group([
    'middleware' => ['auth:api'],
    'prefix' => 'auth'
], function ($router) {
    Route::post('register', [AuthController::class, 'register'])->withoutMiddleware(['auth:api']);
    Route::post('login', [AuthController::class, 'login'])->withoutMiddleware(['auth:api']);
    Route::post('logout', [AuthController::class, 'logout']);
    Route::post('refresh', [AuthController::class, 'refresh']);
    Route::get('user', [AuthController::class, 'me']);
});

AuthController.php
<?php

namespace App\Http\Controllers;

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

class AuthController extends Controller
{
    public function __construct()
    {
        $this->middleware('auth:api', ['except' => ['login']]);
    }

    public function register(Request $request)
    {
        User::create([
            "name" => $request->name,
            "email" => $request->email,
            "password" => Hash::make($request->password)
        ]);

        return response()->json(['message' => 'Successfully user create']);
    }

    public function login()
    {
        $credentials = request(['email', 'password']);

        if (! $token = auth()->attempt($credentials)) {
            return response()->json(['error' => 'Unauthorized'], 401);
        }

        return $this->respondWithToken($token);
    }

    public function me()
    {
        return response()->json(auth()->user());
    }

    public function logout()
    {
        auth()->logout();

        return response()->json(['message' => 'Successfully logged out']);
    }

    public function refresh()
    {
        return $this->respondWithToken(auth()->refresh());
    }

    protected function respondWithToken($token)
    {
        return response()->json([
            'access_token' => $token,
            'token_type' => 'bearer',
            'expires_in' => auth()->factory()->getTTL() * 60
        ]);
    }
}

自分で試したこと

$ php artisan tinkerで>>> DB::connection()->getConfig();と調べたところ、
.envファイルの内容と同じだったためデータベースの方は接続できていると思います。
しかし、nuxtとlaravelでサーバーを立ち上げnuxtで表示されたフロントに名前などを入力してphpmyadminでテーブルの値を確認しても保存されていません。
そのため、nuxtとlaravelがうまく接続できていないと考えていますが、調べましたが分かりませんでした。
どなたかご教授よろしくお願いいたします。

0

1Answer

500 (Internal Server Error)なら、ログを確認してください。
laravel.log > php_errors.log > apache.log

0Like

Comments

  1. @ottott

    Questioner

    laravel.log > php_errors.log > apache.log
    のログの確認がいまいち分からないのですが、Controllerにどこがエラーであるかを分かるようにするメソッドを書いたらいいのでしょうか?

    それとも、http://127.0.0.1:8000/ 
    のconsoleでerrorsを選択して何かやるのでしょうか?
  2. エラーはログに書かれてあるはずです。
    ブラウザーのDeveloper ToolsのNetworkパネルでapiを探して、Responseを見ると詳しく書いてあるかもしれません。

    そもそも人間はコンピューターじゃないので、コードを読むだけでバグを見つけるのは難しいです。ログさえあればバグがある可能性のファイルやセッテイングとかを指摘できるかもしれません。
  3. @ottott

    Questioner

    Networkパネルでresponseを見るとpostとgetが影響してエラーが出ていると分かったのですが、
    どのように変更すれば良いかわからない状態です。
    そのため、もう一度laravelを勉強し直してきます。
    回答ありがとうございました。

Your answer might help someone💌