Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

shalomabitan's avatar

Using Third Party Authentication like Parse or Auth0

Hi,

I am looking to redesign the system I have into a more "laravel" method. I am using a third-party authentication (can't change) for our users and have a postgres database with the users' information. They are obviously tied via a unique identifier and once a user is authenticated I can retrieve whatever data they want. The system is mainly an API, so I wanted to know if you guys have any advice for the following specification:

  1. Want to use Laravel Eloquent more instead of writing all the code myself(e.g. User::find($id), etc)
  2. Want to authenticate via 3rd party system (e.g. parse, auth0) and also use helper methods like Auth::check() etc
  3. Retrieve the user's information and necessary data from our postgres user table once he is authenticated so there would need to be a sort of connection.
  4. Write this in a very 'elegant' manner

I've been looking into laravel's documentation, but, if i'm not mistaken, it assumes that your users and their credentials live on the same table.

Any help, advice would be great.

Thanks

0 likes
42 replies
glena's avatar

Hi,

Did you take a look at the auth0 package for laravel?

I am the guy working on it and it provides an easy way to do what you want. You can extend the user provider to easily fetch and store the user data in your database.

Check the doc for regular webapps https://auth0.com/docs/quickstart/webapp/laravel/ (and there is another one for authenticating requests with JWT).

Let me know if you need a hand and I can guide you and if you have feedback, it is always welcome :)

Daikazu's avatar

HI,

I’m using the Auth0 Package for Laravel and I must say it works great out of the box.

I want to use my own Users database table via Eloquent instead of using the returned auth0 User data. I’ve only been working with Laravel a few months now and I’m trying to figure out how to implement what is described in section 6.2 USING OTHER DRIVER.

I guess this question is best directed to @glena. I don’t seem to understand how to hook into the `onLogin callback function.

This is pretty much what my WelcomeController.php looks like;

public function index()
    {
        $isLoggedIn = \Auth::check();

        if ($isLoggedIn)
        {
            return redirect()->route('dashboard');
        } else
        {
            return redirect()->route('login');
        }
    }


    public function login()
    {
        $auth0Config = config('laravel-auth0');

        return view('welcome.login')->with('auth0Config', $auth0Config);
    }


    public function logout()
    {
        \Auth::logout();

        return redirect()->route('home');
    }

in the vendor/auth0/login/src/controllers/Auth0Controller.php I can see where it looks for it with the if ($service->hasOnLogin()) {…efore it redirects to the root path, but I’m not clear code wise how to “hook” into that.

I was wonderer if you could expand upon this or direct me somewhere to gain a little more insight on how this in done? Any help would be appreciated.

Thanks

glena's avatar

hey @Daikazu

The best way to do this, is to use your own UsersRepository.

Check the last part of the second step on https://auth0.com/docs/quickstart/webapp/laravel

You need to create a class that implements the Auth0UserRepository contract (check the contract https://github.com/auth0/laravel-auth0/blob/master/src/Auth0/Login/Contract/Auth0UserRepository.php).

You can base your on what the default user repository does (check here https://github.com/auth0/laravel-auth0/blob/master/src/Auth0/Login/Repository/Auth0UserRepository.php)

so for example, your getUserByUserInfo method needs, instead of using the user profile from auth0, look if the user with the same user_id exists in your database. If it does, you will return your user if not you will create it.

The same with getUserByIdentifier, instead of fetching the user profile, you can look into your database to see if it exists with this identifier.

makes sense?

1 like
Daikazu's avatar

Thanks @glena ,

I was able to get this working perfectly. It was really easier than I was making it out to be. I really appreciate your input on this.

1 like
shalomabitan's avatar

@glena I set everything up (simple setup, not user repository) according to the doc. do you have any idea why \Auth0:jwtuser() would only give me an object of only five object back? I have not be able to successfully call Auth0:jwtuser()->name. using a clean install of laravel 5.2

{#161
  +"iss": "https://xxxxxx.auth0.com/"
  +"sub": "auth0|xxxxxxxxxxx"
  +"aud": "xxxxxxxxxxxxxxxxxxxxxxx"
  +"exp": 1234567890
  +"iat": 1234567890
}

Actual values removed for obvious reasons.

achegedus's avatar

@glena, i'm hoping you're able to help me.. i'm using auth0 to handle authentication. I'm using the auth0 driver and not persisting data locally. I want to be able to have some methods on my user object, but i don't know where to put them. Is there a best way to do this?

glena's avatar

@achegedus Basically you will need to build your own user object (or extend the auth0's, lets call this new one NewAuth0User) and your own user repository (lets call this one NewAuth0UserRepository).

Your new user should look like this:

<?php namespace App;

use Auth0\Login\Auth0User;

class NewAuth0User extends Auth0User {
    
    public function someNewMethod() {
        ...
    }
}

And the new repo:

<?php namespace App\Repository;

use App\NewAuth0User;
use Auth0\Login\Repository\Auth0UserRepository;

class NewAuth0UserRepository extends Auth0UserRepository {
    
    public function getUserByUserInfo($userInfo) {
            return new NewAuth0User($userInfo['profile'], $userInfo['accessToken']);
        }
}

Then, you can change the binding to use your own UserRepository like this (remember to replace the one you first added, do not keep both bindings):

$this->app->bind(
        '\Auth0\Login\Contract\Auth0UserRepository',
        '\App\Repository\NewAuth0UserRepository');

And that should do the trick. (Remember to check your namespaces and directories where you put this new clases).

1 like
fcarentz's avatar

Trying this to implement the persisted user from the Auth0 Quick start... However nothing I am trying is working. Is there a tutorial as to how to implement this? I am obviously not getting it from this short and sweet explanation in the quickstart.

#6.2. USING OTHER DRIVER

If you want to persist the user you can use the authentication driver you like. The plugin gives you a hook that is called with the Normalized >User Profile when the callback is succesful, there you can store the user structure as you want. For example, if we use Eloquent, we can add >the following code, to persist the user in the database

Auth0::onLogin(function($auth0User) {
    // See if the user exists
    $user = User::where("auth0id", $auth0User->user_id)->first();
    if ($user === null) {
        // If not, create one
        $user = new User();
        $user->email = $auth0User->email;
        $user->auth0id = $auth0User->user_id;
        $user->nickname = $auth0User->nickname;
        $user->name = $auth0User->name;
        $user->save();
    }
    return $user;
});

Note that this hook must return the new user, which must implement the Illuminate\Contracts\Auth\Authenticatable. The onLogin function >is going to be called just once, when the callback uri is called, then its up to the selected auth driver to get the user from the database.

fcarentz's avatar

@glena - Yea I did, but I think maybe I didn't do something else that I was supposed to before it. Honestly Im finding it a tad confusing... for instance, where does this happen or go?

Auth0::onLogin(function($auth0User) {
    // See if the user exists
    $user = User::where("auth0id", $auth0User->user_id)->first();
    if ($user === null) {
        // If not, create one
        $user = new User();
        $user->email = $auth0User->email;
        $user->auth0id = $auth0User->user_id;
        $user->nickname = $auth0User->nickname;
        $user->name = $auth0User->name;
        $user->save();
    }
    return $user;
});

The tut assumes the reader knows Laravel inside out. Unfortunately I've only been working with it for a couple months. And where does my "User Object" go? Is it considered a Model and go in the root of the App directory? Does it matter?

glena's avatar

You can set that on the routes file. The user object in that case is the default User model of your app (as it says on the docs, it could be any Model that implements the Illuminate\Contracts\Auth\Authenticatable contract).

Did you set up the callback url with Route::get('/auth0/callback', '\Auth0\Login\Auth0Controller@callback');? you should go through all the steps.

Anyway, the proper way to do this is doing what I said before. Implement your own UserProvider and your own User model. This way you can store it in the database if you want. I am thinking on deprecate the onLogin event (I am keeping it for BC, but for sure we should remove this from the documentation).

fcarentz's avatar

Yes I set up my call back as Route::get('/auth0/callback', '\Auth0\Login\Auth0Controller@callback');

Just so I know I am understanding. NewAuth0User in your example is in fact a new Model for the User, correct?

jab1000's avatar

Glena, we can only use the Auth0 laravel JWT package as an Auth0 customer - yes? Working to get JWT working across multiple websites (shared customers across 4 total domains) and having challenges with Tymon JWT package.

Yes, I would prefer to use Auth0 but the cost structure doesn't work for B2C SaaS websites.

Thanks!

glena's avatar

@jab1000 The Auth0 Laravel SDK provides you a middleware to authenticate api requests using JWT. Not sure why did you say it wont work for B2C SaaS.

fcarentz's avatar

@glena

Ok, So Don't I also need to update my config/auth.php like so?

    'providers' => [
        'users' => [
            'driver' => 'auth0',
            'model' => App\NewAuth0User::class,
        ],
glena's avatar

@jab1000 I think it should work, anyway, it is open source so you can check how the middleware is implemented and build one on your own based on that, it is pretty straight forward.

jab1000's avatar

@glena - thx, I will check it out since having challenges with Firebase JWT presently not persisting user sessions across page requests. I tried Tymon JWT and it wouldn't ever decode successfully.

FYI, would love to see Auth0 have some other option for B2C -- for instance, our customers are seasonal and we may have one of the 25k+ and another month of 10k and then another at 5k. Yes, I do wish we could charge all of those "users" on our side but as a "team based structure" a larger "pool of users" comes with it.

Thanks again!

glena's avatar

@jab1000 shoot an email to [email protected] and maybe you can work out a plan that work for both, or send one to german (at) auth0 {dot} com, I can put you in touch with one or our sales guys

fcarentz's avatar

Still doesn't seem to be making it to my database.

So... obviously I'm missing something in the setup or somewhere... Thanks for all the help thus far @glena, by the way.

Like, where in the world do I actually put this... I find the instructions very vague.

\Auth0::onLogin(function($auth0User) {
               echo 'FUCK ME';
               die();
                // See if the user exists
                $user = User::where("auth0id", $auth0User->user_id)->first();
                if ($user === null) {
                    // If not, create one
                    $user = new User();
                    $user->email = $auth0User->email;
                    $user->auth0id = $auth0User->user_id;
                    $user->nickname = $auth0User->nickname;
                    $user->name = $auth0User->name;
                    $user->save();
                }
                return $user;
    });

Here is what I have thus far...

auth.php

'providers' => [
        'users' => [
            'driver' => 'eloquent',
            'model' => App\User::class,
        ],

Routes.php

Route::get('/auth0/callback', '\Auth0\Login\Auth0Controller@callback');

User.php (Model)

class User extends Authenticatable implements  \Illuminate\Contracts\Auth\Authenticatable
{
    /**
     * The attributes that are mass assignable.
     *
     * @var array
     */
    protected $fillable = [
        'name', 'email', 'password', 'auth0id', 'firstname', 'lastname', 'picture', 'nickname'
    ];

    /**
     * The attributes that should be hidden for arrays.
     *
     * @var array
     */
    protected $hidden = [
        'password', 'remember_token',
    ];
}

AppServiceProvider.php

public function register()
    {
       
        /*
        $this->app->bind(
            '\Auth0\Login\Contract\Auth0UserRepository',
            '\Auth0\Login\Repository\Auth0UserRepository'
        );
        */
        
        $this->app->bind(
        '\Auth0\Login\Contract\Auth0UserRepository',
        '\App\Repository\NewAuth0UserRepository');
    }

NewAuth0UserRepository

namespace App\Repository;

use App\User;
use Auth0\Login\Repository\Auth0UserRepository;

class NewAuth0UserRepository extends Auth0UserRepository {
    
    public function getUserByUserInfo($userInfo) {
            
            return new User($userInfo['profile'], $userInfo['accessToken']);
        }
}
glena's avatar

You are mixing a lot of stuff there.

First, I would recommend you to not use the login event and use the custom repository.

Second, the user object you have in there does not matches with the one you are instantiating in the repository. You can either construct the User object properly, use the SDK user object (https://github.com/auth0/laravel-auth0/blob/master/src/Auth0/Login/Auth0User.php) or change your User model to comply with that constructor.

Third, did you change the driver in the auth.php file?

If you are using php 5.3, you need to set:

    'providers' => [
        'users' => [
            'driver' => 'auth0'
        ],
    ],

If you are using 5.3, changing 'driver' => 'auth0', should be enough

1 like
fcarentz's avatar

@glena

Ok this is what I have now.

AppServiceProvider

 $this->app->bind(
        '\Auth0\Login\Contract\Auth0UserRepository',
        '\App\Repository\NewAuth0UserRepository');

auth.php

    'providers' => [
        'users' => [
            'driver' => 'auth0'
        ]
    ],

NewAuth0User.php

<?php
namespace App;
use Auth0\Login\Auth0User;

class NewAuth0User extends Auth0User {
    
    public function someNewMethod() {
         // FROM YOUR EXAMPLE
    }
}

NewAuth0UserRepository.php

<?php
namespace App\Repository;
use App\NewAuth0User;
use Auth0\Login\Repository\Auth0UserRepository;

class NewAuth0UserRepository extends Auth0UserRepository {
    
    public function getUserByUserInfo($userInfo) {
            return new NewAuth0User($userInfo['profile'], $userInfo['accessToken']);
        }
}

So now it shows that I am logged in. BUT there is no record saved to the database so I can persist and add to the users data.

fcarentz's avatar

@glena Nevermind. What an idiot I am! LMAO I got it. Sweet lord I was totally over-complicating that in my head. Thank you so much for the assist and patience with my dumb @$$.

  • Frank
Next

Please or to participate in this conversation.