PHPackages                             faithfm/laravel-auth0-pattern - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Templating &amp; Views](/categories/templating)
4. /
5. faithfm/laravel-auth0-pattern

ActiveLibrary[Templating &amp; Views](/categories/templating)

faithfm/laravel-auth0-pattern
=============================

Laravel Authentication using Auth0 (developed for Faith FM projects)

4.0.2(1y ago)1412GPL-3.0-or-laterPHPPHP ^8.0

Since Nov 3Pushed 1y ago1 watchersCompare

[ Source](https://github.com/faithfm/laravel-auth0-pattern)[ Packagist](https://packagist.org/packages/faithfm/laravel-auth0-pattern)[ Docs](https://github.com/faithfm/laravel-auth0-pattern)[ RSS](/packages/faithfm-laravel-auth0-pattern/feed)WikiDiscussions master Synced 1mo ago

READMEChangelogDependencies (7)Versions (16)Used By (0)

laravel-auth0-pattern
=====================

[](#laravel-auth0-pattern)

[![laravel-auth0-pattern-logo.jpg](doc/../docs/laravel-auth0-pattern-logo.jpg)](doc/../docs/laravel-auth0-pattern-logo.jpg)

An opinionated library/pattern for Laravel Authentication (AuthN) and Authorisation (AuthZ) - designed to improve consistency across our Faith FM Laravel/Vue projects.

Much of the functionality of our pattern is now delegated to **3x reusable packages**. These child packages are less opinionated and will be of more widespread interest to other developers:

- [laravel-**simple-auth0**](https://github.com/faithfm/laravel-simple-auth0) - simple **session**-based Authentication using **Auth0**.
- [laravel-**simple-auth-tokens**](https://github.com/faithfm/laravel-simple-auth-tokens) - simple **token**-based Authentication using **API keys** (ie: `?api_token=XXXX`).
- [laravel-**simple-permissions**](https://github.com/faithfm/laravel-simple-permissions) - simple **Permissions** / Authorization Gates using the *'user\_permissions'* table / Eloquent model.

> In v4.0.0 we replaced the official [Auth0 Laravel SDK](https://github.com/auth0/laravel-auth0) with our own lightweight *laravel-simple-auth0* package, and split other functionality into reusable packages. Our *laravel-simple-auth0* uses Laravel's built-in Session-Guard and an Eloquent User model retrieved using the 'sub' identifier provided by a [simple Auth0 PHP flow](https://auth0.com/docs/quickstart/webapp/php)).[1](#user-content-fn-1-bfcf900efbce353a84b0d529c574d748)

Structure:
----------

[](#structure)

Our pattern:

- Imports the 3x reusable packages.
- Publishes a number of opinionated templates that are re-used across our applications.
- Provides configuration and usage instructions and guidance.

The structure of the key files provided by this package (and each of the child packages) is:

[![structure-of-pattern](docs/structure-of-pattern.png)](https://www.canva.com/design/DAGEfYrNYng/rDMsUUS3jrcCMHGQLHMu3g/edit)

Installation and Configuration:
-------------------------------

[](#installation-and-configuration)

- Apply the basic [installation and configuration](docs/installation.md) instructions.
- Configure [external packages](docs/external-package-config.md) such as Laravel Nova and OwenIT Auditing.
- Configure Auth0 *(including allowed callback routes)* and add Auth0 settings to your **.env** file:

Tip

*(It's wise to update **.env.example** template too. See [faithfm/**laravel-simple-auth0**](https://github.com/faithfm/laravel-simple-auth0?tab=readme-ov-file#configuration) package for further details regarding Auth0 configuration, etc.)*

```
AUTH0_DOMAIN=XXXX.xx.auth0.com
AUTH0_CLIENT_ID=XXXXXXXXXXX
AUTH0_CLIENT_SECRET=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
```

- Define the list of allowable Permissions in config/**auth.php**:

```
'defined_permissions' => [
    'use-app',                  // minimum permission to use the app
    'admin-app',                // master admin privilege
//  'edit-catalog',             // for catalog editors  (assuming you're writing a catalogue application)
],
```

- Assign permissions to users via the `user_permissions` table:

Note

*The 'restrictions' column is a JSON field that can **optionally** be used to define specific restrictions/qualifications to a privilege. Ie: our Media project uses 'filter' and 'fields' to restrict users to editing specific files/fields.*

[![user_permissions-table](docs/user_permissions-table.jpg)](docs/user_permissions-table.jpg)

How It Works
------------

[](#how-it-works)

- The /login, /logout, /callback routes that enable session-based authentication are documented in [laravel-**simple-auth0**](https://github.com/faithfm/laravel-simple-auth0?tab=readme-ov-file#how-it-works).
- The `api_key=XXX` token-based authentication is documented in [laravel-**simple-auth-tokens**](https://github.com/faithfm/laravel-simple-auth-tokens?tab=readme-ov-file#how-it-works).
- The [Authorization Gates](https://laravel.com/docs/master/authorization) automatically created for all `'defined_permissions'` in config/**auth.php** are documented in [laravel-**simple-permissions**](https://github.com/faithfm/laravel-simple-permissions).
- Our *User* and *UserPermission* models incorporate the [owen-it/laravel-auditing](https://github.com/owen-it/laravel-auditing) package which is used to audit changes to models across our projects. *(This package is a composer dependency.)*
- Our learnings from developing an understanding of authentication + authorization - particularly in the context of Laravel + Auth0 have been [documented here](docs/underderstanding-laravel-auth0-authn+authz.md) for what they're worth.

Usage
-----

[](#usage)

Our pattern uses non-standard **Authentication Guard** names for [greater clarity and disambiguation](docs/disambiguation-auth-guard-vs-middleware-group-names.md):

- **'web'** (Laravel default) --&gt; **'web\_guard'** (v2.2.0) --&gt; **'ffm-session-guard'** (v3.0.0) \[based on SessionGuard driver\]
- **'api'** (Laravel default) --&gt; **'api\_guard'** (v2.2.0) --&gt; **'ffm-token-guard'** (v3.0.0) \[based on TokenGuard driver\]

**Authentication Examples:**

Apart from that our pattern supports all Laravel's normal [authentication](https://laravel.com/docs/master/authentication) (AuthN) methods to check if logged in, protect routes, retrieve a user, etc:

```
// Check a user is logged in - using a variety of methods   (default guard is our session-based Auth0 guard)
$loggedIn = auth()->check();                         // using helper function  (default guard)
$loggedIn = Auth::check();                           // using Facades          (default guard)
$loggedIn = auth('ffm-session-guard')->check();      // session-based guard specified - ie: using Auth0
$loggedIn = auth('ffm-token-guard')->check();        // token-based guard specified - ie: api_token=XXX
$loggedIn = Auth::guard('ffm-token-guard')->check(); // token-based guard specified using Facades

// Various useful guard functions - using the helper function and the default guard
auth()->user()          // Eloquent model for the logged-in User
auth()->id()            // User ID for this user - ie: user()->getAuthIdentifier()
auth()->check()         // TRUE  if logged in
auth()->guest()         // FALSE if logged in
auth()->authenticate()  // throw AuthenticationException if not logged in  (similiar to middleware checks)

// Protect routes using 'auth' (Authenticate) middleware - throw AuthenticationException if not logged in
Route::get(...) { ... }
  ->middleware('auth');                                   // using default guard
  ->middleware('auth:ffm-token-guard');                   // specifying token-based guard
  ->middleware('auth:ffm-session-guard,ffm-token-guard'); // allow EITHER session-based OR token-based guards
```

When multiple alternative guards have been specified via middleware (ie: the last example above), all authentication calls inside this route are implicitly resolved using the first authenticated guard that was found: *(The middleware calls the shouldUse() method which overrides the configured default guard.)*

```
Route::get('/showuser', function () {
    return auth()->user();	// session-based or token-based guard will automatically be used depending on first authenticated guard found during middleware check
})->middleware('auth:ffm-session-guard,ffm-token-guard');
```

We also have created an extended `auth_guards()` helper that allows **multiple guards** to be specified, since unfortunately neither Laravel's `guard()` helper nor `Auth::guard()` facade support multiple guards **outside** of a middleware-protected-route - ie:

```
$user = auth()->user();                 // default guard   = SUPPORTED
$user = auth('api')->user();            // specific guard  = SUPPORTED
$user = auth('web,api')->user();        // multiple guards = NOT SUPPORTED
$user = auth_guards('web,api')->user(); // multiple guards = SUPPORTED (extended helper)
```

**Authorization Examples:**

Check for **permissions** (AuthZ) using the [Authorization Gates](https://laravel.com/docs/master/authorization) that have been automatically created for all `'defined_permissions'` in config/**auth.php**:

```
$allowed = Gate::allows('use-app');             // simple test
$allowed = Gate::allows('use-app|edit-assets'); // ORed permissions (SPECIAL FEATURE)
...->middleware('can:use-app');                 // protect in route definitions
Gate::authorize('use-app|admin-app');           // protect elsewhere (ie: controllers)
if (Gate::none(['use-app', 'admin-app'])) {     // ditto - but manually aborting (instead of relying on "401 vs redirect" recommendation - see installation.md)
    abort(403);
}
@can('use-app')                                 // blade templates
```

Important

Notice the special '|' character that can be used to test multiple (ORed) permissions in a single gate. This is an extension to Laravel's normal functionality.

More complex restrictions-field checking/filtering has currently only been implemented in the front-end (see next section)... but in the mean-time we could potentially use something like this: (UNTESTED)

```
if (Gate::allows('use-app'))
  if (auth()->user()->permissions->restrictions['file'] == 'restrictedfile')
    // ALLOW/DENY STUFF FROM HAPPENING
```

Extended Usage: Vue front-end
-----------------------------

[](#extended-usage-vue-front-end)

`LaravelUserPermissions.js` is a helper library that allows permission-checks to be performed in the front-end.

This helper assumes that user permissions are passed from back-end to front-end using a global javascript `LaravelAppGlobals` variable (which is usually passed by the Blade file). Specifically it is looking for the existence of the global `LaravelAppGlobals.user.permissions` property.

Simple permission checks use the `laravelUserCan()` function:

```
import { laravelUserCan } from "../LaravelUserPermissions";
if (laravelUserCan("use-app"))
  // ALLOW STUFF TO HAPPEN
```

More complex restrictions checks/filtering uses the `laravelUserRestrictions()` function:

```
import { laravelUserRestrictions } from "../LaravelUserPermissions";
const restrictions = laravelUserRestrictions("use-app");
if (restrictions.status == "NOT PERMITTED")
  // PREVENT STUFF FROM HAPPENING
if (restrictions.status == "ALL PERMITTED")
  // UNFILTERED ACCESS
if (restrictions.status == "SOME PERMITTED") {
  // PARTIAL/FILTERED ACCESS BASED ON RESTRICTIONS JSON DATA - IE: ASSUMING 'filter' field
  if (currentItem.startsWith(restrictions.filter)
    // DO STUFF IF FILTER ALLOWS
```

In the '*restrictions*' field example from our Media project above, the *restrictions* object returned by the `laravelUserRestrictions()` function would have been:

```
{
  status: "SOME PERMITTED",
  fields: ["content","guests"],
  filter: "file:sa/*"
}
```

The value of the *status* field will be:

- `NOT PERMITTED` - if the requested permission (ie: "use-app") does not exist for the user.
- `ALL PERMITTED` - if the requested permission does exist... AND the *'restrictions'* field is blank.
- `SOME PERMITTED` - if the requested permission does exist... AND the *'restrictions'* field contains valid JSON data.

The remaining fields (ie: *fields* and *filter* in this example) are directly copied from the *'restrictions'* JSON data in the database.

Important

REMINDER: according to good security practice you should not rely only upon front-end checks to enforce security, but should perform security checks in the back-end too.

Sample code to pass permissions via LaravelAppGlobals to front-end
------------------------------------------------------------------

[](#sample-code-to-pass-permissions-via-laravelappglobals-to-front-end)

```
  $LaravelAppGlobals = [
    'user' => auth()->user(),     # THIS IS THE IMPORTANT ONE
    'guest' => auth()->guest(),
    'other-stuff' => $myStuff,
    ...
  ];
  return view('media')->with('LaravelAppGlobals', $LaravelAppGlobals);
```

```

        var LaravelAppGlobals = Object.freeze({!! json_encode($LaravelAppGlobals) !!});

...
```

---

Our applications are stateful "PHP Web Applications" (rather than stateless "PHP Backend APIs" interfacing to an SPA with JWTs), and we did not need a lot of the advanced features included in the Laravel SDK - which tended to increase the compexity unnecessarily and proved a source of pain to reintegrate with each major update.

A significant source of pain has been that the "user provider" for the Auth0 package does not (by default) provide a regular Eloquent model... and we found the hard way that many packages (including Laravel Nova) tend to break when something other than a is returned by a user provider.

Recent versions of the Auth0 package have improved compatibiliy for providing genuine Eloquent models, and have removed the need for many of the hacks we had to apply in earlier versions, however after spending many hours creating v3.0.0 of our package to align with improved design patterns in Auth0's package we realised that our User Repository is still building layers of complexity on top of an already-complex solution.

Comparing these many complex layers with the simplicity of [Auth0's PHP QuickStart](https://auth0.com/docs/quickstart/webapp/php), our [laravel-**simple-auth0**](https://github.com/faithfm/laravel-simple-auth0) package now uses Auth0 **only** to validate a user and provide us a unique *'sub'* identifier. This identifier is then used to retrieve a User model... which is passed to Laravel's built-in SessionGuard... which retrieves this same user model for subsequent authentication requests for the duration of a valid session.

Footnotes
---------

1. Rationale for moving away from the official [Laravel SDK](https://github.com/auth0/laravel-auth0) (`auth0/login` package) provided by Auth0: We developed our own simple Auth0 package for Laravel (in v4.0.0) after spending a many hours re-integrating this pattern (and all of our Laravel apps) to retain compatibility with the changing patterns used in each major update of Auth0's official Laravel package. [↩](#user-content-fnref-1-bfcf900efbce353a84b0d529c574d748)

###  Health Score

32

—

LowBetter than 72% of packages

Maintenance31

Infrequent updates — may be unmaintained

Popularity12

Limited adoption so far

Community12

Small or concentrated contributor base

Maturity63

Established project with proven stability

 Bus Factor1

Top contributor holds 59.1% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~66 days

Recently: every ~89 days

Total

15

Last Release

721d ago

Major Versions

1.1.0 → 2.0.02022-11-08

2.2.1 → 3.0.02024-05-02

3.0.0 → 4.0.02024-05-14

PHP version history (3 changes)1.0.5PHP ^7.2

1.1.0PHP ^7.2|^8.0

2.0.0PHP ^8.0

### Community

Maintainers

![](https://www.gravatar.com/avatar/bb7c991e0e25b4d43bacd4a88ef7a67f2d0665ddf6980cc8dceeeba94cfc3a9b?d=identicon)[miking7](/maintainers/miking7)

![](https://www.gravatar.com/avatar/29ec36050b27f6835414c1a11c7b8b1121a0725dcf3c6a9a45104b336529c926?d=identicon)[lidiaordonez](/maintainers/lidiaordonez)

---

Top Contributors

[![miking7](https://avatars.githubusercontent.com/u/5072816?v=4)](https://github.com/miking7 "miking7 (13 commits)")[![lidiaordonez](https://avatars.githubusercontent.com/u/52942074?v=4)](https://github.com/lidiaordonez "lidiaordonez (9 commits)")

---

Tags

composerpackagetemplate

### Embed Badge

![Health badge](/badges/faithfm-laravel-auth0-pattern/health.svg)

```
[![Health](https://phpackages.com/badges/faithfm-laravel-auth0-pattern/health.svg)](https://phpackages.com/packages/faithfm-laravel-auth0-pattern)
```

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
