Laravel 10 User in session changes after login when using HashI

41 views Asked by At

// Authcontroller.php


  public function user(GetUser $getUser, HashIdService $hashIdService)
    {
        $user = auth()->user();

        $decodedUserId = $hashIdService->decode($user->id);

        return $getUser($decodedUserId);
    }


 public function login(LoginRequest $loginRequest, LoginUser $loginUser, HashIdService $hashIdService)
    {
        return $loginUser($loginRequest, $hashIdService);
    }

// GetUser.php

<?php

namespace App\Actions\Users;

use App\Models\User;

class GetUser
{
    public function __invoke($decodedUserId)
    {
        // get user profile based on id
        try {
            $userProfile = User::with('profile', 'role:id,role_name', 'group:id,group_name')
                ->join('user_profiles', 'users.id', '=', 'user_profiles.user_id')
                ->select('users.*', 'user_profiles.status_id', 'user_profiles.updated_by', 'user_profiles.distributor_id', 'user_profiles.operator_id')
                ->where('users.id', $decodedUserId)
                ->first();

            return response()->json([
                'isSuccess' => true,
                'user'      => $userProfile,
            ]);
        } catch (\Throwable $th) {
            //throw $th;
            return response()->json([
                'isSuccess' => false,
                'message'   => $th->getMessage(),
            ], 500);
        }
    }
}

// LoginUser.php

<?php

namespace App\Actions\Users;

use App\Http\Requests\Auth\LoginRequest;
use App\Models\User;
use App\Services\HashIdService;
use Illuminate\Support\Facades\Log;

class LoginUser
{
    public function __invoke(LoginRequest $request, HashIdService $hashIdService)
    {
        try {
            $request->authenticate();

            // Use the authenticated user's ID directly
            $userId = auth()->id();

          
            $userProfile = User::with('profile', 'role:id,role_name', 'group:id,group_name')
                ->join('user_profiles', 'users.id', '=', 'user_profiles.user_id')
                ->select('users.*', 'user_profiles.status_id', 'user_profiles.updated_by')
                ->where('users.id', $hashIdService->decode($userId))
                ->first();

            return response()->json($userProfile, 200);
        } catch (\Throwable $th) {
            // Log the exception details
            Log::error($th);

            return response()->json(
                [
                    'isSuccess' => false,
                    'message'   => $th->getMessage(),
                ],
                404,
            );
        }
    }
}

// HashIdService.php

<?php

namespace App\Services;

use Hashids\Hashids;

class HashIdService
{
    public function __construct(
        public $hashIds = new Hashids('', 20, 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890'),
    ) {
    }

    public function encode($id)
    {
        return $this->hashIds->encode($id);
    }

    public function decode($hashId)
    {
        if (is_int($hashId)) {
            return $hashId;
        }

        $decodedIds = $this->hashIds->decode($hashId);

        if (count($decodedIds) > 1) {
            return intval($decodedIds);
        } else {
            return intval($decodedIds[0]);
        }
    }
}

// User.php

<?php

namespace App\Models;

// use Illuminate\Contracts\Auth\MustVerifyEmail;

use App\Casts\UserHashId;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Laravel\Sanctum\HasApiTokens;

class User extends Authenticatable
{
    use HasApiTokens, HasFactory, Notifiable;

    public function profile()
    {
        return $this->hasOne(UserProfile::class, 'user_id', 'id');
    }

    public function distributor()
    {
        return $this->hasOne(Distributor::class, 'email', 'email');
    }

    public function temporaryPassword()
    {
        return $this->hasOne(TemporaryPasswords::class, 'user_id', 'id');
    }

    public function group()
    {
        return $this->hasOne(UserGroup::class, 'id', 'group_id');
    }

    public function role()
    {
        return $this->hasOne(UserRole::class, 'id', 'role_id');
    }

    /**
     * The attributes that are mass assignable.
     *
     * @var array<int, string>
     */
    protected $fillable = ['name', 'email', 'password', 'role_id', 'group_id'];

    /**
     * The attributes that should be hidden for serialization.
     *
     * @var array<int, string>
     */
    protected $hidden = ['password', 'remember_token'];

    /**
     * The attributes that should be cast.
     *
     * @var array<string, string>
     */
    protected $casts = [
        'id'      => UserHashId::class,
        'user_id' => UserHashId::class,

        'email_verified_at' => 'datetime',
        'password'          => 'hashed',
    ];
}

// UserHashId.php

<?php

namespace App\Casts;

use App\Services\UserHashIdService;
use Illuminate\Contracts\Database\Eloquent\CastsAttributes;
use Illuminate\Database\Eloquent\Model;

class UserHashId implements CastsAttributes
{
    /**
     * Cast the given value.
     *
     * @param  array<string, mixed>  $attributes
     */
    public function get(Model $model, string $key, mixed $value, array $attributes): mixed
    {
        // Ensure that the value is not null before encoding
        if ($value !== null) {
            return (new UserHashIdService())->encode($value);
        }

        return $value;
    }

    /**
     * Prepare the given value for storage.
     *
     * @param  array<string, mixed>  $attributes
     */
    public function set(Model $model, string $key, $value, array $attributes)
    {
        // Ensure that the value is not null before decoding
        if ($value !== null) {
            $decodedValue = (new UserHashIdService())->decode($value);

            return $decodedValue !== $decodedValue ? $decodedValue : $value;
        }

        return $value;
    }
}

when i apply this to protected cast User model

 'id'      => UserHashId::class,
        'user_id' => UserHashId::class,

I can't get the User who currently logged in

After I logged in, when getting the user changes in the session,

but when i uncomment / removed the HashId::class to id , i can get the user who loggedin

Any experiencing this?

I used laravel sanctum and react for its frontend

// api.php

Route::post('/login', [AuthController::class, 'login']);

Route::group(['middleware' => ['auth:sanctum']], function () {

   Route::get('/user', [AuthController::class, 'user']);

});

Troubleshooting this for a month

I want to apply hashing id to users but its not working as expected

0

There are 0 answers