21

I was using Laravel's built-in api token authentication before but I wanted to provide multiple api tokens for different clients and with Laravel 7.x, I'm trying to migrate to Laravel Sanctum.

API seems authenticates user without any problem but when I try to get user data with Auth::user();, it returns null. Also  Auth::guard('api')->user(); returns null too.

What should I use as Auth guard? Or is it correct way to get user data based on provided token?

Thank you very much....

she hates me
  • 1,212
  • 5
  • 25
  • 44
  • Was a custom middleware used for the authentication? If you did and the problem is not resolved, can post the contents of the middleware? – qwertynik Jan 30 '21 at 13:59
  • Use either `@parsa-samandizadeh` solution, or use an optional sanctum auth middleware as described in: https://laracasts.com/discuss/channels/laravel/laravel-sanctum-optional-auth-on-route?page=1&replyId=680807 – armezit Mar 31 '22 at 12:21
  • Did you put "Bearer " before token string to header.Authorization field on Request. – ÄR Âmmãř Żąîñh Apr 04 '22 at 09:20

9 Answers9

37

auth('sanctum')->user()->id
auth('sanctum')->check()


without middleware, you could use these.
27

First, route through the sanctum auth middleware.

Route::get('/somepage', 'SomeController@MyMethod')->middleware('auth:sanctum');

Then, get the user.

namespace App\Http\Controllers;

use Illuminate\Http\Request;

class AuthController extends Controller
{
    public function MyMethod(Request $request) {
        return $request->user();
    }
}

auth()->user() is a global helper, Auth::user() is a support facade, and $request->user() uses http. You can use any of them. For a quick test, try

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

Be sure to send your token in a header like so:

Authorization: Bearer UserTokenHere
Maik Lowrey
  • 15,957
  • 6
  • 40
  • 79
Gavin
  • 293
  • 2
  • 4
  • 3
    unforturnately for API requests, $request->user() and auth()->user() returns null. Auth::user() returns null as well (seems requires guard provided) – she hates me Jul 16 '20 at 20:16
  • @shehatesme Did you send the token in a header with the request like above? – Gavin Jul 16 '20 at 20:18
  • @shehatesme You need to use the `auth:sanctum` middleware otherwise it will return null – Liga Jan 22 '21 at 15:40
3

Authorization header

Send token in the Authorization header, below code return the auth user.

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

In case of restful api, suggest you to send Accept header also for checking at authenticate middleware for redirection if not authenticated. By default for restful api it redirect to login form (if any) if user not authenticated.

namespace App\Http\Middleware;

protected function redirectTo($request)
{
    if (!$request->expectsJson()) {
        return route('login');
    }
}
Aniket Muruskar
  • 267
  • 3
  • 9
3

The simplest way to to that is to use auth helpers like

$user =  auth('sanctum')->user();

Or you can get it by the request object

//SomeController.php
public function exampleMethod(Request $request)
{
   $user = $request->user();
}

To get user by sactum token string like

2|bTNlKViqCkCsOJOXWbtNASDKF7SyHwzHOPLNH

Code be like

use Laravel\Sanctum\PersonalAccessToken;
//...
$token = PersonalAccessToken::findToken($sactumToken);
$user = $token->tokenable;

Note: The most way to pass token is from Authorization headers by bearer

Pascal Tovohery
  • 888
  • 7
  • 19
1

When you are logging in the user, in your login function use something like this

public function login(Request $request)
{
    if(Auth::attempt($credentials))
    {
         $userid = auth()->user()->id;
    }
}

Then send this user id to the client and let it store in a secured way on client-side. Then with every request, you can use this user-id to serve data for next requests.

Maik Lowrey
  • 15,957
  • 6
  • 40
  • 79
adir1521
  • 124
  • 2
  • 12
0
 private $status_code= 200; // successfully

    public function register(Request $request)
    {
        // $validator = $this->validator($request->all())->validate();
        $validator = Validator::make($request->all(),
            [
                'name' => ['required', 'string', 'max:255'],
                'email' => ['required', 'string', 'email', 'max:255'], // , 'unique:users'
                'password' => ['required', 'string', 'min:4'],
            ]
        );
        if($validator->fails()) {
            return response()->json(["status" => "failed", "message" => "Please Input Valid Data", "errors" => $validator->errors()]);
        }
        $user_status = User::where("email", $request->email)->first();
        if(!is_null($user_status)) {
           return response()->json(["status" => "failed", "success" => false, "message" => "Whoops! email already registered"]);
        }

        $user = $this->create($request->all());
        if(!is_null($user)) {
            $this->guard()->login($user);
            return response()->json(["status" => $this->status_code, "success" => true, "message" => "Registration completed successfully", "data" => $user]);
        }else {
            return response()->json(["status" => "failed", "success" => false, "message" => "Failed to register"]);
        }
    }
    /**
     * Get a validator for an incoming registration request.
     *
     * @param  array  $data
     * @return \Illuminate\Contracts\Validation\Validator
     */
    protected function validator(array $data)
    {
        return Validator::make($data, [
            'name' => ['required', 'string', 'max:255'],
            'email' => ['required', 'string', 'email', 'max:255', 'unique:users'],
            'password' => ['required', 'string', 'min:4'],
        ]);
    }

    /**
     * Create a new user instance after a valid registration.
     * @author Mohammad Ali Abdullah .. 
     * @param  array  $data
     * @return \App\User
     */
    protected function create(array $data)
    {
        return User::create([
            'name' => $data['name'],
            'email' => $data['email'],
            'password' => Hash::make($data['password']),
        ]);
    }
    protected function guard()
    {
        return Auth::guard();
    }
    /**
     * method public
    * @author Mohammad Ali Abdullah
    * @date 01-01-2021.
    */
    public function login(Request $request)
    {

        $validator = Validator::make($request->all(),
            [
                "email"             =>          "required|email",
                "password"          =>          "required"
            ]
        );
        // check validation email and password .. 
        if($validator->fails()) {
            return response()->json(["status" => "failed", "validation_error" => $validator->errors()]);
        }
        // check user email validation ..
        $email_status = User::where("email", $request->email)->first();
        if(!is_null($email_status)) {
            // check user password validation ..
            // ---- first try -----
            // $password_status    =   User::where("email", $request->email)->where("password", Hash::check($request->password))->first();
            // if password is correct ..
            // ---- first try -----
            // if(!is_null($password_status)) {
            if(Hash::check($request->password, $email_status->password)) {
                $credentials = $request->only('email', 'password');
                if (Auth::attempt($credentials)) {
                    // Authentication passed ..
                    $authuser = auth()->user();
                    return response()->json(["status" => $this->status_code, "success" => true, "message" => "You have logged in successfully", "data" => $authuser]);
                }
            }else {
                return response()->json(["status" => "failed", "success" => false, "message" => "Unable to login. Incorrect password."]);
            }
        }else{
            return response()->json(["status" => "failed", "success" => false, "message" => "Email doesnt exist."]);
        }
    }

    public function logout()
    {
        Auth::logout();
        return response()->json(['message' => 'Logged Out'], 200);
    }
0

I see that no answer has been accepted yet. I just had the problem that my sacntum auth did not work. The auth() helper always returned null.

To solve the problem I removed the comment in the kernel.php under the api key. It is about this class \Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful::class. This is because it is commented out by default.

'api' => [
    \Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful::class,
    'throttle:api',
    \Illuminate\Routing\Middleware\SubstituteBindings::class,
],

After that I had access to the User object with the auth() helper.

Maik Lowrey
  • 15,957
  • 6
  • 40
  • 79
-1

Make sure the sanctum middleware is in api

  • 1
    Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Oct 27 '21 at 12:30
-1

I was in the same boat; migrated to Sanctum and wondered why all of my $request->user() were empty. The solution for me was to throw some middleware onto the stack to modify the request's user() resolver:

namespace App\Http\Middleware;

use Illuminate\Http\Request;

class PromoteSanctumUser
{
    /**
     * @param Request $request
     * @param \Closure $next
     */
    public function handle(Request $request, \Closure $next)
    {
        $sanctumUser = auth('sanctum')->user();

        if ($sanctumUser) {
            $request->setUserResolver(function() use ($sanctumUser) {
                return $sanctumUser;
            });
        }

        return $next($request);
    }
}
Nimantha
  • 6,405
  • 6
  • 28
  • 69
Plywood
  • 891
  • 1
  • 7
  • 16