質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.47%
Next.js

Next.jsは、Reactを用いたサーバサイドレンダリングなどを行う軽量なフレームワークです。Zeit社が開発しており、nextコマンドでプロジェクトを作成することにより、開発環境整備が整った環境が即時に作成できます。

Laravel

LaravelとはTaylor Otwellによって開発された、オープンソースなPHPフレームワークです。Laravelはシンプルで表現的なシンタックスを持ち合わせており、ウェブアプリケーション開発の手助けをしてくれます。

Q&A

1回答

145閲覧

next.js laravel sanctum ログイン認証の問題

maibear3

総合スコア5

Next.js

Next.jsは、Reactを用いたサーバサイドレンダリングなどを行う軽量なフレームワークです。Zeit社が開発しており、nextコマンドでプロジェクトを作成することにより、開発環境整備が整った環境が即時に作成できます。

Laravel

LaravelとはTaylor Otwellによって開発された、オープンソースなPHPフレームワークです。Laravelはシンプルで表現的なシンタックスを持ち合わせており、ウェブアプリケーション開発の手助けをしてくれます。

0グッド

1クリップ

投稿2024/03/13 10:48

実現したいこと

フロントはnext.js
バックエンドはlaravelを使用しています。
ログインページでメールアドレスとパスワードでログインしマイページに遷移。
その後現在のユーザー情報を取得したい

発生している問題・分からないこと

マイページ遷移後にusers/meでユーザー情報を取得することができない

このトークンをcookieに持たせておいて
apiClient.get('/api/users/me');で自動的に渡すようにすることは可能なのでしょうか?
ローカルストレージに保持しておく以外の方法を模索しています。

エラーメッセージ

error

1GET http://localhost/api/users/me 401 (Unauthorized) 2Mypage.tsx:34 予期しないエラー: 3AxiosError {message: 'Request failed with status code 401', name: 'AxiosError', code: 'ERR_BAD_REQUEST', config: {…}, request: XMLHttpRequest, …} 4code 5: 6"ERR_BAD_REQUEST" 7config 8: 9{transitional: {…}, adapter: Array(2), transformRequest: Array(1), transformResponse: Array(1), timeout: 0, …} 10message 11: 12"Request failed with status code 401" 13name 14: 15"AxiosError" 16request 17: 18XMLHttpRequest {onreadystatechange: null, readyState: 4, timeout: 0, withCredentials: true, upload: XMLHttpRequestUpload, …} 19response 20: 21{data: {…}, status: 401, statusText: 'Unauthorized', headers: AxiosHeaders, config: {…}, …} 22stack 23: 24"AxiosError: Request failed with status code 401\n at settle (webpack-internal:///(app-pages-browser)/../node_modules/axios/lib/core/settle.js:21:16)\n at XMLHttpRequest.onloadend (webpack-internal:///(app-pages-browser)/../node_modules/axios/lib/adapters/xhr.js:106:72)\n at Axios.request (webpack-internal:///(app-pages-browser)/../node_modules/axios/lib/core/Axios.js:40:49)\n at async MyPage (webpack-internal:///(app-pages-browser)/./src/components/Mypage.tsx:16:33)" 25[[Prototype]] 26: 27Error 28MyPage @ Mypage.tsx:34 29Show 16 more frames

該当のソースコード

Login.tsx

Mypage.tsx

1"use client"; 2import React, { useEffect, useState } from 'react'; 3import { useRouter } from 'next/navigation'; 4 5import apiClient from '@/utils/axios'; 6 7const MyPage = async () => { 8 const router = useRouter(); 9 10 try { 11 const { data, error } = await apiClient.get('/api/users/me'); 12 13 if (error) { 14 // エラー処理を改善 15 console.error(error); 16 if (error.response?.status !== 409) throw error; // レスポンスステータスを確認 17 router.push('/'); 18 } 19 20 // 成功した場合、ユーザーデータを表示 21 return ( 22 <div> 23 <h1>マイページ</h1> 24 {data && ( 25 <div> 26 <p>名前:{data.name}</p> 27 <p>メールアドレス:{data.email}</p> 28 </div> 29 )} 30 </div> 31 ); 32 } catch (error) { 33 34 console.error("予期しないエラー:", error); 35 36 } 37}; 38 39export default MyPage; 40

axios.tsx

1import Axios from 'axios' 2 3const apiClient = Axios.create({ 4 baseURL: process.env.NEXT_PUBLIC_LARAVEL_APP_URL, 5 headers: { 6 'X-Requested-With': 'XMLHttpRequest', 7 }, 8 withCredentials: true, 9}) 10 11export default apiClient 12

api.php

1<?php 2 3use Illuminate\Http\Request; 4use Illuminate\Support\Facades\Route; 5use App\Models\User; 6 7 8Route::post('/register', 'App\Http\Controllers\AuthController@register'); 9Route::post('/login', 'App\Http\Controllers\AuthController@login'); 10Route::get('/users/me', 'App\Http\Controllers\AuthController@me')->middleware('auth:sanctum'); 11

AuthController.php

1<?php 2 3namespace App\Http\Controllers; 4 5use App\Models\User; 6use Illuminate\Http\Request; 7use Illuminate\Http\Response; 8use Illuminate\Support\Facades\Hash; 9use Illuminate\Support\Facades\Auth; 10 11class AuthController extends Controller 12{ 13 // ユーザー登録 14 public function register(Request $request) { 15 $user = User::create([ 16 'name' => $request->name, 17 'email' => $request->email, 18 'password' => Hash::make($request->password), 19 ]); 20 $json = [ 21 'data' => $user 22 ]; 23 return response()->json( $json, Response::HTTP_OK); 24 } 25 26 public function login(Request $request) 27 { 28 29 $user = User::where('email', $request['email'])->firstOrFail(); 30 31 $token = $user->createToken('auth_token')->plainTextToken; 32 33 return response()->json([ 34 'access_token' => $token, 35 'token_type' => 'Bearer', 36 ]); 37 } 38 39 public function me(Request $request) 40 { 41 Log::info('Request data:', $request->all()); 42 return $request->user(); 43 } 44} 45

試したこと・調べたこと

  • teratailやGoogle等で検索した
  • ソースコードを自分なりに変更した
  • 知人に聞いた
  • その他
上記の詳細・結果

postmanで
http://localhost/api/users/me
に対してget通信でログイン時の
http.post('/api/login', { email, password }).then((res) => {
console.log(res.data);//トークンの値
で取得したトークンを一緒に渡したらユーザー情報が帰ってきました。

補足

laravel 10.38.2
next.js 14.1
docker

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

naomina121

2024/03/14 03:07 編集

laravel標準搭載のlaravel-sanctumとかいい感じだと思います。 と書いていて、質問で既にsenctumを使われていましたね、失礼しました。 >このトークンをcookieに持たせておいて apiClient.get('/api/users/me');で自動的に渡すようにすることは可能なのでしょうか? ↓sanctumの基本仕様です。ですので実装できます。 1.HasApiTokensトレイトやpersonal_access_tokensテーブルは不要: これらは通常、APIとの認証に使われるものですが、この場合には必要ありません。 2.トークンベースの認証を使わない: SPAでよく見られるトークンを使った認証方法ではなく、異なる方法を採用します。 3.クッキーベースのセッション認証を使用する: Laravelが提供する標準的なセッション認証システムを利用します。これは、ブラウザのクッキーを用いて認証情報を管理する方法です。 4.web認証ガードを利用する: Laravelのweb認証ガード機能を活用し、認証プロセスを強化します。 5.セキュリティ対策を施す: CSRF保護を使用してセキュリティを確保し、セッション認証の利点を活かし、XSS攻撃を通じた認証情報の漏洩を防ぎます。 6.認証手順: まずクッキーによる認証を試み、クッキーが存在しない場合はAPIトークンによる認証を行います。 7.ドメイン要件: SPAとAPIは同じトップレベルドメインを共有する必要がありますが、サブドメインが異なっても構いません。 app/Http/Kernel.php 'api' => [ // コメントアウトされている記述を有効にする \Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful::class, \Illuminate\Routing\Middleware\ThrottleRequests::class.':api', \Illuminate\Routing\Middleware\SubstituteBindings::class, ], >この記述を有効にすることで、Sanctumのミドルウェアがapi ミドルウェアグループに追加されます。 >これでLaravelのAPIへのリクエストでセッション・Cookieによる認証をすることが可能になります。 Cookieによる認証は可能です。 ↓詳しくは下記の記事に紹介されています。 参考リンク【Laravel + Next.js】Sanctumを使ってSPA認証を実装する https://qiita.com/masakiwakabayashi/items/58734b3988d5fac814fb
maibear3

2024/03/14 05:45

ご回答、参考ページを教えていただきありがとうございます。 そちらのサイト通りログインまでは完成しました。 その後ログイン後にマイページに遷移した際に現在のユーザー名などを取得するためにマイページ遷移後に /api/users/meに対してget通信を飛ばして public function me(Request $request) { Log::info('Request data:', $request->all()); return $request->user(); } が動くようにしたいです。 /api/users/meに対してget通信を飛ばすさいに、どういうアクションをかければユーザー情報が帰ってきてくれるのか悩んでいるところです。 上記を調べてもいい記事が見つけられず解決できなかったので今回質問を作成いたしました
guest

回答1

0

公式から出てるbreeze-nextは参考になると思います。
https://github.com/laravel/breeze-next

僕はいつもlaravelとnextの連携で使ってます。
page routerでもapp routerでも問題なく動きます。

react

1const ExamplePage = () => { 2 const { logout, user } = useAuth({ middleware: 'auth' }) 3 4 return ( 5 <> 6 <p>{user?.name}</p> 7 8 <button onClick={logout}>Sign out</button> 9 </> 10 ) 11} 12 13export default ExamplePage

内部でuseSWRを使ってるので{ middleware: 'auth' }をつけるとログインしてなかったりセッションが切れると強制的にログインページに飛ばしてくれます

sanctum入れてるならbreezeじゃなくて自前でログイン周り実装してても問題なかったと思います

投稿2024/04/12 10:58

tomoto

総合スコア11

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.47%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問