hope you doing well. I've just migrated from react to next and im struggling a little bit with it.
Im redoing the same REST API i've done with react/laravel a while ago but this time with next/laravel.
I found that the way we set our private routes and auth is not the same that we usually do in react. I dont want to use NextAuth, i want to set my own. That's why i've created a file for axios and another one for auth, but im not sure if is writed the right way.
In laravel im using sanctum, having my own middleware.
Im going to share with you the code and see if you can help me or guide on how to do it following my needs.
Thanks in advance !
This is the AUTH on Next :
import { useRouter } from "next/router";
import { useEffect, useState } from "react";
import axios from "../lib/axios";
import Swal from 'sweetalert2';
export const useAuth = () => {
const router = useRouter();
const swal = Swal();
const [loading, setLoading] = useState(true);
const [adminAuthenticated, setAdminAuthenticated] = useState(false);
useEffect(() => {
axios.get(`/api/checkAuthenticated`).then((res) => {
if (res.status === 200) {
setAdminAuthenticated(true);
}
setLoading(false);
});
return () => {
setAdminAuthenticated(false);
};
}, []);
axios.interceptors.response.use(undefined, function axiosRetryInterceptor(err) {
if (err.response.status === 401) {
swal("Unauthorized", err.response.data.message, "warning");
router.push('/homepage');
}
return Promise.reject(err);
});
axios.interceptors.response.use(function (response) {
return response;
}, function (error) {
if (error.response.status === 403)// acces denied
{
swal('Forbidden', error.response.data.message, "warning");
router.push('403')
}
else if (error.response.status === 404)// page not found
{
swal('404 Error', "Url/Page Not Found", "warning");
router.push('404')
}
return Promise.reject(error);
}
);
if(loading)
{
return <h1>Loading...</h1>
}
}
This is the file i created for Axios :
import Axios from "axios";
const axios = Axios.create({
baseURL: process.env.NEXT_PUBLIC_BACKEND_URL,
headers: {
'X-Requested-With': 'XMLHttpRequest',
'Content-Type': 'application/json',
'Accept': 'application/json'
},
withCredentials: true
});
axios.interceptors.request.use(function (config) {
const token = localStorage.getItem('auth_token');
config.headers.Authorization = token ? `Bearer ${token}` : '';
return config;
});
export default axios;
' NEXT_PUBLIC_BACKEND_URL = "http://localhost:8000"; ' is on my '.env.local' file .
Now i will show you my laravel code.
Here API ROUTES:
Route::post('login', [AuthController::class, 'login']);
Route::middleware(['auth:sanctum', 'isAPIAdmin'])->group(function () {
Route::get('/checkAuthenticated', function () {
return response()->json(['message' => 'You are in', 'status' => 200], 200);
});
)};
Here my Auth Controller:
<?php
namespace App\Http\Controllers\API;
use App\Http\Controllers\Controller;
use App\Models\User;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Validator;
class AuthController extends Controller
{
public function login(Request $request)
{
$validator = Validator::make($request->all(), [
'email'=>'required|max:191',
'password'=>'required',
]);
if($validator->fails())
{
return response()->json([
'validation_errors'=>$validator->errors(),
]);
}
else
{
$user = User::where('email', $request->email)->first();
if(! $user || ! Hash::check($request->password, $user->password))
{
return response()->json([
'status'=>401,
'message'=>'WRONG DATA',
]);
}
else
{
if($user->type == 1)
{
$type = "1";
$token = $user->createToken($user->email.'_AdminToken', ['server:admin'])->plainTextToken;
}
return response()->json([
'status'=>200,
'username'=>$user->name,
'token'=>$token,
'message'=>'CONECTED',
'type' => $type,
]);
}
}
}
public function logout() {
auth()->user()->tokens()->delete();
return response()->json(['message' => 'DISCONNECTED'], 200);
}
}
Here is my middleware :
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
class ApiAdmin
{
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure(\Illuminate\Http\Request): (\Illuminate\Http\Response|\Illuminate\Http\RedirectResponse) $next
* @return \Illuminate\Http\Response|\Illuminate\Http\RedirectResponse
*/
public function handle(Request $request, Closure $next)
{
if(Auth::check()){
if(auth()->user()->type == '1')
{
return $next($request);
}
else
{
return response()->json([
'message'=>'Acces denied, who are you ? !',
], 403);
}
}
else
{
return response()->json([
'status'=>401,
'message'=>'Please, try to login again !',
]);
}
}
}
Any information on how to adapt this to Next will be helpful. Im new to this so im finding hard to understand it the correct way. Thanks again !