Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Session Error: Invalid text representation #301

Closed
bkilshaw opened this issue Aug 24, 2022 · 1 comment
Closed

Session Error: Invalid text representation #301

bkilshaw opened this issue Aug 24, 2022 · 1 comment

Comments

@bkilshaw
Copy link

bkilshaw commented Aug 24, 2022

SDK Version

7.0

PHP Version

PHP 8.1

Composer Version

2.x

What happened?

Laravel's default session table sets the user_id column to INT4 but after following the Auth0 Laravel setup guide it attempts to set it to a string which throws the error.

SQLSTATE[22P02]: Invalid text representation: 7 ERROR: invalid input syntax for integer: "auth0|72398a0fa2a6f17f7a3" 

How can we reproduce this issue?

Follow the https://auth0.com/docs/quickstart/webapp/laravel/ guide and set your session driver to database

SESSION_DRIVER=database

Additional context

No response

@evansims
Copy link
Member

evansims commented Aug 25, 2022

Hi, @bkilshaw 👋 Thanks for raising this issue! Sorry to hear you're hitting a challenge there.

Our Quickstart is admittedly focused more on the out-of-the-box default Laravel configuration. In terms of drivers, there are so many configuration variations possible it would be hard to cover every option in the QS — and while there isn't ever a one-size-fits-all approach to this sort of thing, I think a custom user model and repository would be a great solution to what you're looking for here.

The issue is, as you noticed, Auth0's unique identifier is always a string — and that database driver you've enabled expects the id to be an integer. You need a solution to either change the database schema to accept a string or implement a way of reshaping the unique identifier into something usable for your database storage.

For simplicity's sake, and to demo custom user modeling and repositories, here's one solution that should work: create a CRC32 checksum of the Auth0 unique identifier, which results in an integer that should work for your database schema.

<?php

declare(strict_types=1);

namespace App\Auth;

class CustomUserRepository implements \Auth0\Laravel\Contract\Auth\User\Repository
{
    public function fromSession(
        array $user
    ): ?\Illuminate\Contracts\Auth\Authenticatable {
        return new \App\Models\User([
            'id' => crc32($user['sub'] ?? $user['user_id'] ?? 0),
            'name' => $user['name'],
            'email' => $user['email'],
        ]);
    }

    public function fromAccessToken(
        array $user
    ): ?\Illuminate\Contracts\Auth\Authenticatable {
        // Not relevant for stateful sessions
        return null;
    }
}

For additional control over how the user object is shaped, you can use a completely custom user model to customize the object to your application's needs. For example, in the user repository above, we're returning a custom user model, App\Models\User. This is what a structure for that custom model might look like:

<?php

declare(strict_types=1);

namespace App\Models;

use Auth0\Laravel\Contract\Model\Stateful\User as StatefulUser;
use Illuminate\Auth\Authenticatable;
use Illuminate\Contracts\Auth\Authenticatable as AuthenticatableUser;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Notifications\Notifiable;

class User extends \Illuminate\Database\Eloquent\Model implements StatefulUser, AuthenticatableUser
{
    use HasFactory, Notifiable, Authenticatable;

    /**
     * The primary identifier for the user.
     *
     * @var string
     */
    protected $primaryKey = 'id';

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

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

    /**
     * The attributes that should be cast.
     *
     * @var array<string, string>
     */
    protected $casts = [];
}

Don't forget to tell the SDK that you want to use a custom user repository if you go this route, by updating your config/auth.php file:

    'providers' => [
        //...

        'auth0' => [
            'driver' => 'auth0',
            'repository' => App\Auth\CustomUserRepository::class
        ],
    ],

This is, of course, just a rough example — you'd need to validate that this is the right approach for your application's needs and tweak it as necessary. More information on custom user providers can be found in the README: https://github.com/auth0/laravel-auth0/blob/main/README.md#custom-user-models-and-repositories

I should note that unless you have a particular reason for your application to persist sessions to a database, there really isn't any need to do this — the Auth0 SDK handles sessions internally, so it's a bit redundant. You might be storing more in your sessions than just token/user data, though.

Let me know if you have any further questions! (Going to close this as it isn't a bug and the initial question can be considered answered, but feel free to keep the discussion going here.)

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Sep 26, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants