DEV Community

Arne
Arne

Posted on

Auth0 with Laravel 5.4 including saving the user

Disclaimer: Sorry for my english, not my mother tongue.. but i try my best.

Vacation after I managed to recover from Wacken 2017, the rest of the time is once again put into some fun with PHP and Laravel.

For a small project where a user administration is necessary, I was recently recommended by a colleague the service auth0.

What is auth0? It takes you all the effort to include various authentication providers such as Facebook, Google, Github, and so on. In the free version somewhat limited, but for a beginning more than sufficient (7000 User, 2 Provider).

Well now it was time to connect my Laravel application to auth0. The documentation is quite good (also related to the integration in Laravel) but when i tried to save the users into my own databases, the examples did not work. So if you have to accomplish the same task, or if i have to do it again.. here comes a small tutorial.

As a starting point, let’s assume:

  • Laravel 5.4 application works, and the migrations for the users (are already there) were executed
  • Auth0 account is set up

For the most times we will follow their documentation, with some small changes.

Integrate Auth0 in Laravel 5.4

In your project directory, we install us first the right package for Auth0

composer require auth0/login:"~5.0"
Enter fullscreen mode Exit fullscreen mode

Now change your: /config/app.php

<?php
'providers' => array(
    Auth0\Login\LoginServiceProvider::class,
);
'aliases'array( 
    'Auth0' => Auth0\Login\Facade\Auth0::class 
);
Enter fullscreen mode Exit fullscreen mode

Now we differ from the documentation, since we want to save our users in our databases. For this we build a UserRepository: /app/Repository/UserRepository.php with the following content:

<?php
namespace App\Repository;
use Auth0\Login\Contract\Auth0UserRepository as Auth0UserRepository;
use App\User as User;
class UserRepository implements Auth0UserRepository {
    public function getUserByDecodedJWT($jwt)
    {
        $jwt->user_id = $jwt->sub;
        return $this->upsertUser($jwt);
    }
    public function getUserByUserInfo($userInfo)
    {
        return $this->upsertUser((object) $userInfo['profile']);
    }
    /**
     * Check if user is in database, if not create.
     * 
     * @return User 
     */
    protected function upsertUser($profile) {
        $user = User::where("auth0id", $profile->user_id)->first();
        // create user if not in database
        if ($user === null) {
            $user = new User();
            $user->email = $profile->email;
            $user->auth0id = $profile->user_id;
            $user->name = $profile->name;
            // random password, we dont need it 
            $user->password = md5(time());
            $user->save();
        }
        return $user;
    }
    public function getUserByIdentifier($identifier)
    {
        //Get the user info of the user logged in (probably in session)
        $user = \App::make('auth0')->getUser();
        if ($user === null) return null;
        // build the user
        $user = $this->getUserByUserInfo($user);
        // it is not the same user as logged in, it is not valid
        if ($user && $user->id == $identifier) {
            return $user;
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

We do not set a password, the login is managed via auth0. What you still have to do is to insert the column auth0id in the user table, which of course, Laravel does not know before. The ID is used for the assignment.

The repository will now be registered in our AppServiceProvider: /app/Providers/AppServiceProvider.php

<?php
   /**
     * Register any application services.
     *
     * @return void
     */
    public function register()
    {
        $this->app->bind(
          Auth0UserRepositoryContract::class,
          UserRepository::class // das unser Repository - in der Doku wird Auth0Repo.. genutzt
        );
    }

Enter fullscreen mode Exit fullscreen mode

Now it goes to the configuration. For this, we create the necessary configuration files, and also set the necessary routes for the service.

php artisan vendor:publish
Enter fullscreen mode Exit fullscreen mode

File: /routes/web.php

Route::get('/login', ['as' => 'login', 'uses' => 'IndexController@login']);
Route::get('/logout', ['as' => 'logout', 'uses' => 'IndexController@logout']);
Route::get('/callback', '\Auth0\Login\Auth0Controller@callback');

Enter fullscreen mode Exit fullscreen mode

The functions in the IndexController are as follows:

<?php

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

        return view('index')
              ->with('isLoggedIn', $isLoggedIn)
              ->with('user', \Auth::user());
    }

    public function login()
    {
        return \App::make('auth0')->login();
    }

    public function logout()
    {
        \Auth::logout();
        return \Redirect::intended('/');
    }
Enter fullscreen mode Exit fullscreen mode

So it is already clear, how you later access the user data: \Auth::user(); Now we need to include auth0 as userprovider: /app/config/auth.php

    'providers' => [
        'users' => [
            'driver' => 'auth0',
        ],
Enter fullscreen mode Exit fullscreen mode

Settings for the application

To get the necessary parameters for our configuration, we visit the website of Auth0. You have to create a basic web application there, and set the following URLs.

-Callback: http://dein-server.de/callback
-Logout: http://dein-server.de/logout

The whole should also work with “localhost if you do not have a domain yet.

For the configuration of the applications we still need:

-Domain
-ClientID
-ClientSecret

In your /app/config/laravel-auth0.php you now either set directly the values or use your “.env file.

Testing auth0

If you now call http://dein-server.de/login, you should seea login and then in your user object the corresponding data as well as an entry in the Users database table.

What is missing in the documentation: How do I actually protect a route? Simply add the Auth-Middleware to your route.

# monitor (protected)
Route::get('/monitor/id/{id?}/{title?}', 'MonitorController@show')
    ->middleware('auth')
    ->name('monitor.show');

Route::get('/monitor/create', 'MonitorController@create')
    ->middleware('auth')
    ->name('monitor.create');
Enter fullscreen mode Exit fullscreen mode

Thats it! — if you prefer a german version of this visit my GeekPub

Top comments (3)

Collapse
 
ophasnoname profile image
Arne

It's implemented in the UserRepository:

    protected function upsertUser($profile) {

        $user = User::where("auth0id", $profile->user_id)->first();

        // create user if not in database
        if ($user === null) {
            $user = new User();
            $user->email = $profile->email;
            $user->auth0id = $profile->user_id;
            $user->name = $profile->name;
            $user->password = md5(time());
            $user->save();
        }

        return $user;
    }
Collapse
 
ioncode profile image
Andrey Ponteleev

same question, how you implemented recieving userinfo ?

in docs we see:
$user->email = $profile->email; // you should ask for the email scope
$user->auth0id = $profile->user_id;
$user->name = $profile->name; // you should ask for the name scope

auth0.com/docs/quickstart/backend/...

Collapse
 
williamnwogbo profile image
Nwogbo William

the problem is the fact that the profile array being return is always empty