Search code examples
laravelmiddlewarecustom-authentication

I'm checking in middleware if a user is logged in then he needs no header if user is not logged in and in api call he needs to add header token


I'm checking in the middleware if a user is logged in. If so, then he doesn't need a header. If a user is not logged in and in an API call, he needs to add a header token. I'm facing an issue in (Auth::check()). It is not working fine

public function handle(Request $request, Closure $next)
{
    if (!Auth::check()) {
        $token = $request->header('APP_KEY');
        $from = intval(time() / 3600 - 1);
        $to = intval(time() / 3600);
        $condition1 = md5('ABCD'.$from);
        $condition2 = md5('ABCD'.$to);

        if ($token == null) {
            return response()->json(['message' => 
                'App key not Found or user is not Login '], 401);
        } else if ($token == $condition1 || $token == $condition2) {
            return $next($request);
        } else {
            return response()->json(['message' => 
                "App Key Not Matched".$condition1], 401);
        }
    } else {
        return $next($request);
    }
}

Solution

  • You need to set the token in the cookie when user logged In successfully:

        // user login
        public function login(Request $request) {
            $request->validate([
                'email' => 'required|string|email|max:255',
                'password' => 'required|string|min:6',
            ]);
            $user = User::where('email', $request->email)->first();
            if (!$user) {
                return response()->json([
                    'success' => false,
                    'message' => 'User not found',
                ], 404);
            }
            if (!Hash::check($request->password, $user->password)) {
                return response()->json([
                    'success' => false,
                    'message' => 'Password is incorrect',
                ], 404);
            }
            $token = $user->createToken('Laravel Password Grant Client')->plainTextToken;
    
            $cookie = cookie('token', $token, 60 * 24 * 30);
    
            return response()->json([
                'success' => true,
                'message' => 'User logged in successfully',
            ])->withCookie($cookie);
        }
    

    After that you have to go this file and add the following codes in handle method. app\Http\Middleware\Authenticate.php

        public function handle($request, Closure $next, ...$guards) {
    
            if ($token = $request->cookie('token')) {
                $request->headers->set('Authorization', 'Bearer ' . $token);
            }
    
            $this->authenticate($request, $guards);
    
            return $next($request);
        }
    

    In this way when you consume login API in your SPA the token will be stored in the browser's cookie (httpOnly) and then you can consume other API which is protected routes with no token in headers (It means you don't have to pass token in the header in any request after login).

    And to remove token from both server and browsers's cookie then you can use this below code in logout method.

    // user logout
        public function logout(Request $request) {
            $request->user()->tokens()->delete();
            $cookie = Cookie::forget('token');
    
            return response()->json([
                'success' => true,
                'message' => 'User logged out successfully',
            ])->withCookie($cookie);
        }