実現したいこと
フロントは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
1"use client"; 2import React, { useContext } from 'react'; 3import { Button, Input, PasswordInput } from '@mantine/core'; 4import axios from 'axios'; 5import { useRouter } from 'next/navigation'; 6 7const http = axios.create({ 8 baseURL: 'http://localhost', 9 withCredentials: true, 10}); 11 12const Login = () => { 13 const [email, setEmail] = React.useState(''); 14 const [password, setPassword] = React.useState(''); 15 const router = useRouter(); 16 17 const postData = async () => { 18 axios.get('http://localhost/sanctum/csrf-cookie', { withCredentials: true }).then((res: any) => { 19 console.log(res.data); 20 console.log("CSRF Cookie set successfully."); 21 http.post('/api/login', { email, password }).then((res) => { 22 console.log(res.data);//トークンの値 23 router.push('/mypage'); 24 }).catch((error) => { 25 console.error("Login failed:", error); 26 }); 27 }); 28 }; 29 30 return ( 31 <div style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center', minHeight: '100vh' }}> 32 <h2>ログインページ</h2> 33 <div style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center', minHeight: '20vh', border: '1px solid #ccc', borderRadius: '5px', padding: '3%', marginBottom: '2%' }}> 34 <div style={{ display: 'grid', margin: '1%' }}> 35 <label htmlFor="email">Email</label> 36 <Input 37 placeholder="Email" 38 style={{ width: '300px' }} 39 value={email} 40 onChange={(e) => setEmail(e.target.value)} 41 /> 42 </div> 43 44 <div style={{ display: 'grid', margin: '1%' }}> 45 <label htmlFor="password">Password</label> 46 <PasswordInput 47 placeholder="Password" 48 style={{ width: '300px' }} 49 value={password} 50 onChange={(e) => setPassword(e.target.value)} 51 /> 52 </div> 53 </div> 54 55 <Button onClick={postData}>ログイン</Button> 56 </div> 57 ); 58}; 59 60export default Login; 61
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