Vinotaz
Vinotaz

Reputation: 99

Illuminate\Auth\AuthenticationException when implement two AuthController (web and api) in same project Laravel 7

I created a Laravel App. It could access through web, for admin's web page, and api for user's page. I created user's page using Vue so it needs API. Doing so, I need two Auth Controller. One is automatically created using laravel scaffolding, for the web. And the other is created manually for user's login via token. I did create the AuthController for API. This is the controller.

 <?php

namespace App\Http\Controllers\API;

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

class AuthController extends Controller
{

    //untuk login
    public function login(Request $request)
    {
        //validasi data
        $this->validate($request, [
            'email' => 'email',
            'username' => 'string',
            'password' => 'required'
        ]);
        //login dapat menggunakan email atau username
        $user = User::where('email', '=', $request->email)
            ->orWhere('username', '=', $request->username)->first();
//        $username = User::where('username', $request->username)->first();
//        dd($username);
        $status = "error";
        $message = "";
        $data = null;
        $code = 401;
//        echo (gettype($email));
//        echo(gettype($username));
//        echo($email);
    if($user){
        if (Hash::check($request->password, $user->password)){
            $user->generateToken(); //generated 60 random string
            $status = 'success';
            $message = 'Login Success';
            //tampilkan data user menggunakan method to Array
            $data = $user->toArray();
            $code = 200;
        }
        else{
            $message = "Login gagal, password salah";
        }
    }
    else {
        $message = "Login gagal, username atau email salah";
    }

    return response()->json([
        'status' => $status,
        'message' => $message,
        'data' => $data,
    ], $code);
}

//untuk registrasi
public function register(Request $request)
{
    $validator = Validator::make($request->all(),
    [
        'name' => 'required|string|max:255',
        'email' => 'required|string|email|max:255|unique:users',
        'password' => 'required|string|min:6',
        'username' => 'string'
    ]);

    if ($validator->fails()){
        $errors = $validator->errors();
        return response()->json([
            'data' => [
                'message' => $errors,
            ]
        ],400);
    }
    else{
        $user = User::create([
            'name' => $request->name,
            'email' => $request->email,
            'password' => Hash::make($request->password),
            'username' => $request->username,
            'roles' => json_encode(['CUSTOMER'])
        ]);

        if ($user){
            $user->generateToken();
            $status = "success";
            $message = "Register berhasil!";
            $data = $user->toArray();
            $code = 200;
        }
        else{
            $message = "Register gagal";
        }
        return response()->json([
            'status' => $status,
            'message' => $message,
            'data' => $data
        ], $code);
    }

}

//untuk logout
public function logout(Request $request)
{
    //get authenticated user data
    $user = Auth::user();
    if($user){
        $user->api_token = null; //delete user's token
        $user->save();
    }
    return response()->json([
        'status' => 'success',
        'message' => 'logout success,
        'data' => null,
    ], 200);
}
}

Login and Register method is worked. But when i try to run Logout method, i get AuthenticationException. I tried to debug the $user variable at Logout method, it return null. So, that's why i get the error. My question is, how i solve it? Is it even possible to create two different authentication controller in laravel?

For clarity, this is my api.php

 //Routing bersifat publik
Route::prefix('v1')->group(function (){
    Route::post('login', 'API\AuthController@login');
    Route::post('register', 'API\AuthController@register');
    Route::get('books', 'API\ApiBookController@index');
    Route::get('book/{id}', 'API\ApiBookController@view')
        ->where('id', '[0-9]+');
    Route::resource('categories', 'API\ApiCategoryController')
    ->except(['create', 'update']);

    //Routing bersifat private
    Route::middleware('auth:api')->group(function (){
        Route::post('logout', 'API\AuthController@logout');
    });
});

Logout method response:

{
"status": "error",
"message": "Unauthenticated.",
"data": null,
"errors": {
    "exception": "Illuminate\\Auth\\AuthenticationException",
    "trace": [
        "#0 D:\\xampp\\htdocs\\book-store\\vendor\\laravel\\framework\\src\\Illuminate\\Auth\\Middleware\\Authenticate.php(68): Illuminate\\Auth\\Middleware\\Authenticate->unauthenticated(Object(Illuminate\\Http\\Request), Array)"
]
    }
}

Thank you for your time and consideration.

config\auth.php

'defaults' => [
        'guard' => 'web',
        'passwords' => 'users',
    ],
'guards' => [
        'web' => [
            'driver' => 'session',
            'provider' => 'users',
        ],

        'api' => [
            'driver' => 'token',
            'provider' => 'users',
            'hash' => false,
        ],
    ],

*Note: default guard in config\auth.php is web so i can log in to the web.

Upvotes: 0

Views: 1893

Answers (2)

alirezadp10
alirezadp10

Reputation: 183

you have to specific what user should be logout in your controller in the apiController you should change

$user = Auth::user();

to

$user = Auth::guard('api')->user();;

then logout him.

Upvotes: 0

albus_severus
albus_severus

Reputation: 3702

Use auth guard..

$user=Auth::guard('api')->user();

Upvotes: 0

Related Questions