Farirai's avatar

Getting error Object of class Closure could not be converted to string

I created two apis the first one generates an auth tokens 127.0.0.1:8000/setup and one i got the token i went to post on authorization i put the token i got from /setup route then i send a post request to route 127.0.0.1:8000/api/V1/users but now im moving to production and want an easier way of authorising maybe adding the auth token at the end of the second route my web.php ```<?php

use App\Models\User; use Illuminate\Http\Request; use Illuminate\Support\Facades\Auth; use Illuminate\Support\Facades\Hash; use Illuminate\Support\Facades\Route;

/* |-------------------------------------------------------------------------- | Web Routes |-------------------------------------------------------------------------- | | Here is where you can register web routes for your application. These | routes are loaded by the RouteServiceProvider and all of them will | be assigned to the "web" middleware group. Make something great! | */

Route::get('/', function () { return view('welcome'); });

Route::get('/setup', function () { if (Auth::check()) { $user = Auth::user(); } else { $user = new User(); $user->title = 'Mr'; $user->first_name = 'John'; $user->last_name = 'Makai'; $user->address = '[email protected]'; $user->password = Hash::make('password2'); $user->id_number = '127758595950'; $user->number = '263781840678';

    $user->save();

    Auth::login($user);
}

$adminToken = $user->createToken('admin-token', [
    'create',
    'update',
    'delete',
]);
$updateToken = $user->createToken('update-token', ['create', 'update']);
$createToken = $user->createToken('create-token', ['create']);

return [
    'admin' => $adminToken->plainTextToken,
    'create' => $createToken->plainTextToken,
    'update' => $updateToken->plainTextToken,
];

});

my api.php ```<?php

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Route;
use App\Http\Controllers\Api\V1\UserController;

/*
|--------------------------------------------------------------------------
| API Routes
|--------------------------------------------------------------------------
|
| Here is where you can register API routes for your application. These
| routes are loaded by the RouteServiceProvider and all of them will
| be assigned to the "api" middleware group. Make something great!
|
*/

Route::middleware('auth:sanctum')->get('/user', function (Request $request) {
    return $request->user();
});

Route::group(
    [
        'prefix' => 'V1',
        'namespace' => 'App\Http\Controllers\Api\V1',
        'middleware' => 'auth:sanctum',
    ],
    function () {
        Route::apiResource('users', UserController::class);
    }
)->middleware(function ($request, $next) {
    if ($request->has('token')) {
        $token = $request->input('token');
        $user = \App\Models\User::where('api_token', $token)->first();
        if ($user) {
            auth()->login($user);
        }
    }
    return $next($request);
});
0 likes
1 reply
LaryAI's avatar
Level 58

The error "Object of class Closure could not be converted to string" occurs when a closure is passed as a parameter where a string is expected. In this case, it is likely that the closure is being passed as a parameter to a function that expects a string.

To fix this error, you need to identify where the closure is being passed as a parameter and modify the code to pass a string instead.

One possible solution is to modify the api.php file to accept the token as a parameter in the URL instead of as a query parameter. This can be done by modifying the Route::group definition as follows:

Route::group(
    [
        'prefix' => 'V1',
        'namespace' => 'App\Http\Controllers\Api\V1',
        'middleware' => 'auth:sanctum',
    ],
    function () {
        Route::apiResource('users', UserController::class);
    }
)->middleware(function ($request, $next) {
    $token = $request->route('token');
    if ($token) {
        $user = \App\Models\User::where('api_token', $token)->first();
        if ($user) {
            auth()->login($user);
        }
    }
    return $next($request);
});

With this modification, you can pass the token as a parameter in the URL like this: 127.0.0.1:8000/api/V1/users/{token}.

Note that you will also need to modify the UserController to handle the case where the user is not authenticated.

1 like

Please or to participate in this conversation.