PHPackages                             slowcheetah/laravel-keycloak-web-guard - 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. [Authentication &amp; Authorization](/categories/authentication)
4. /
5. slowcheetah/laravel-keycloak-web-guard

ActiveLibrary[Authentication &amp; Authorization](/categories/authentication)

slowcheetah/laravel-keycloak-web-guard
======================================

Simple Keycloak Guard to Laravel Web Routes With User Sync and User Create Interfaces

v3.1.1(3y ago)04MITPHP

Since Nov 7Pushed 3y agoCompare

[ Source](https://github.com/slowcheetah/laravel-keycloak-web-guard)[ Packagist](https://packagist.org/packages/slowcheetah/laravel-keycloak-web-guard)[ Docs](https://github.com/slowcheetah/laravel-keycloak-web-guard)[ RSS](/packages/slowcheetah-laravel-keycloak-web-guard/feed)WikiDiscussions master Synced 1mo ago

READMEChangelog (2)Dependencies (1)Versions (4)Used By (0)

Fork of

Keycloak Web Guard for Laravel
==============================

[](#keycloak-web-guard-for-laravel)

This packages allow you authenticate users with [Keycloak Server](https://www.keycloak.org).

It works on front. For APIs we recommend [laravel-keycloak-guard](https://github.com/robsontenorio/laravel-keycloak-guard).

Requirements
------------

[](#requirements)

- Have a Keycloak Server.
- Have a realm configured and a client that accepts authentication.

### Support

[](#support)

This package was tested with:

- Laravel: 5.8 / 7 / 8 / 9
- Keycloak: 11.0.3 / 18.0.0

Any other version is not guaranteed to work.

*This is project is open source and maintained on my free time. So, if you have any problem you can open a Issue with all details (laravel version, keycloak version, the description of problem...) and I'll be happy to try to help.*

The flow
--------

[](#the-flow)

1. User access a guarded route and is redirected to Keycloak login.
2. User signin and obtains a code.
3. He's redirected to callback page and we change the code for a access token.
4. We store it on session and validate user.
5. User is logged.
6. We redirect the user to "redirect\_url" route (see config) or the intended one.

Install
-------

[](#install)

Require the package

```
composer require vizir/laravel-keycloak-web-guard

```

If you want to change routes or the default values for Keycloak, publish the config file:

```
php artisan vendor:publish  --provider="SlowCheetah\KeycloakWebGuard\KeycloakWebGuardServiceProvider"

```

Configuration
-------------

[](#configuration)

After publishing `config/keycloak-web.php` file, you can change the routes:

```
'redirect_url' => '/admin',

'routes' => [
    'login' => 'login',
    'logout' => 'logout',
    'register' => 'register',
    'callback' => 'callback',
]
```

Change any value to change the URL.

Other configurations can be changed to have a new default value, but we recommend to use `.env` file:

- `KEYCLOAK_BASE_URL`

The Keycloak Server url. Generally is something like: `https://your-domain.com/auth`.

- `KEYCLOAK_REALM`

The Keycloak realm. The default is `master`.

- `KEYCLOAK_REALM_PUBLIC_KEY`

The Keycloak Server realm public key (string).

In dashboard go to: Keycloak &gt;&gt; Realm Settings &gt;&gt; Keys &gt;&gt; RS256 &gt;&gt; Public Key.

- `KEYCLOAK_CLIENT_ID`

Keycloak Client ID.

In dashboard go to: Keycloak &gt;&gt; Clients &gt;&gt; Installation.

- `KEYCLOAK_CLIENT_SECRET`

Keycloak Client Secret. If empty we'll not send it to Token Endpoint.

In dashboard go to: Keycloak &gt;&gt; Clients &gt;&gt; Installation.

- `KEYCLOAK_CACHE_OPENID`

We can cache the OpenId Configuration: it's a list of endpoints we require to Keycloak.

If you activate it, *remember to flush the cache* when change the realm or url.

Just add the options you would like as an array to the" to "Just add the options you would like to guzzle\_options array on keycloak-web.php config file. For example:

Laravel Auth
------------

[](#laravel-auth)

You should add Keycloak Web guard to your `config/auth.php`.

Just add **keycloak-web** to "driver" option on configurations you want.

As my default is web, I add to it:

```
'guards' => [
    'web' => [
        'driver' => 'keycloak-web',
        'provider' => 'users',
    ],

    // ...
],
```

And change your provider config too:

```
'providers' => [
    'users' => [
        'driver' => 'keycloak-users',
        'model' => App\User::class,
        'modelSearchField' => 'email',  // field in User model for searching
        'keyCloakSearchField' => 'id',
        'userCreator' => App\KeyCloak\UserCreator::class,  // class mast implement SlowCheetah\KeycloakWebGuard\Contracts\CreateUserInterface
        'syncUser' => App\KeyCloak\SyncUser::class,  // class mast implement SlowCheetah\KeycloakWebGuard\Contracts\SyncUserInterface
    ],

    // ...
]
```

API
---

[](#api)

We implement the `Illuminate\Contracts\Auth\Guard`. So, all Laravel default methods will be available.

Ex: `Auth::user()` returns the authenticated user.

Roles
-----

[](#roles)

You can check user has a role simply by `Auth::hasRole('role')`;

This method accept two parameters: the first is the role (string or array of strings) and the second is the resource.

If not provided, resource will be the client\_id, which is the regular check if you authenticating into this client to your front.

### Keycloak Web Gate

[](#keycloak-web-gate)

You can use [Laravel Authorization Gate](https://laravel.com/docs/7.x/authorization#gates) to check user against one or more roles (and resources).

For example, in your Controller you can check **one role**:

```
if (Gate::denies('keycloak-web', 'manage-account')) {
  return abort(403);
}
```

Or **multiple roles**:

```
if (Gate::denies('keycloak-web', ['manage-account'])) {
  return abort(403);
}
```

And **roles for a resource**:

```
if (Gate::denies('keycloak-web', 'manage-account', 'another-resource')) {
  return abort(403);
}
```

*This last use is not trivial, but you can extend the Guard to request authentication/authorization to multiple resources. By default, we request only the current client.*

### Keycloak Can Middleware

[](#keycloak-can-middleware)

If you do not want to use the Gate or already implemented middlewares, you can check user against one or more roles using the `keycloak-web-can` Middleware.

Add this to your Controller's `__construct` method:

```
$this->middleware('keycloak-web-can:manage-something-cool');

// For multiple roles, separate with '|'
$this->middleware('keycloak-web-can:manage-something-cool|manage-something-nice|manage-my-application');
```

This middleware works searching for all roles on default resource (client\_id).

You can extend it and register your own middleware on Kernel.php or just use `Auth::hasRole($roles, $resource)` on your Controller.

FAQ
---

[](#faq)

### I cannot find my login form.

[](#i-cannot-find-my-login-form)

We register a `login` route to redirect to Keycloak Server. After login we'll receive and proccess the token to authenticate your user.

There's no login/registration form.

### How can I protect a route?

[](#how-can-i-protect-a-route)

Just add the `keycloak-web` middleware:

```
// On RouteServiceProvider.php for example

Route::prefix('admin')
  ->middleware('keycloak-web')
  ->namespace($this->namespace)
  ->group(base_path('routes/web.php'));

// Or with Route facade in another place

Route::group(['middleware' => 'keycloak-web'], function () {
    Route::get('/admin', 'Controller@admin');
});
```

### Where the access/refresh tokens and state are persisted?

[](#where-the-accessrefresh-tokens-and-state-are-persisted)

On session. We recommend implement the database driver if you have load balance.

### What's a state?

[](#whats-a-state)

State is a unique and non-guessable string used to mitigate CSRF attacks.

We associate each authentication request about to be initiated with one random state and check on callback. You should do it if you are extending/implementing your own Auth controller.

Use `KeycloakWeb::saveState()` method to save the already generated state to session and `KeycloakWeb::validateState()` to check the current state against the saved one.

### I'm having problems with session (stuck on login loop)

[](#im-having-problems-with-session-stuck-on-login-loop)

For some reason Laravel can present a problem with EncryptCookies middleware changing the session ID.

In this case, we will always try to login, as tokens cannot be retrieved.

You can remove session\_id cookie from encryption:

```
// On your EncryptCookies middleware

class EncryptCookies extends Middleware
{
    protected $except = [];

    public function __construct(EncrypterContract $encrypter)
    {
        parent::__construct($encrypter);

        /**
         * This will disable in runtime.
         *
         * If you have a "session.cookie" option or don't care about changing the app name
         * (in another environment, for example), you can only add it to "$except" array on top
         */
        $this->disableFor(config('session.cookie'));
    }
}
```

### My client is not public.

[](#my-client-is-not-public)

If your client is not public, you should provide a `KEYCLOAK_CLIENT_SECRET` on your `.env`.

### How can I override the default Guzzle options?

[](#how-can-i-override-the-default-guzzle-options)

In some use cases you may need to override the default Guzzle options - likely either to disable SSL verification or to set a Proxy to route all requests through.

Every [Guzzle Request Option](http://docs.guzzlephp.org/en/stable/request-options.html) is supported and is passed directly to the Guzzle Client instance.

Just add the options you would like to `guzzle_options` array on `keycloak-web.php` config file. For example:

```
'guzzle_options' => [
    'verify' => false
]

```

Developers
----------

[](#developers)

- Mário Valney [@mariovalney](https://twitter.com/mariovalney)
- [Vizir Software Studio](https://vizir.com.br)

With contributors on GitHub ❤️

###  Health Score

23

—

LowBetter than 27% of packages

Maintenance20

Infrequent updates — may be unmaintained

Popularity3

Limited adoption so far

Community15

Small or concentrated contributor base

Maturity48

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 70.8% 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 ~0 days

Total

2

Last Release

1283d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/65922d425ae46d17a51830e79d3bbdbb51ad9be264bf56b0879552dd43bc2008?d=identicon)[slowcheetah](/maintainers/slowcheetah)

---

Top Contributors

[![mariovalney](https://avatars.githubusercontent.com/u/5784633?v=4)](https://github.com/mariovalney "mariovalney (80 commits)")[![slowcheetah](https://avatars.githubusercontent.com/u/11753373?v=4)](https://github.com/slowcheetah "slowcheetah (9 commits)")[![MatthewHallCom](https://avatars.githubusercontent.com/u/1230091?v=4)](https://github.com/MatthewHallCom "MatthewHallCom (8 commits)")[![serumk](https://avatars.githubusercontent.com/u/12942167?v=4)](https://github.com/serumk "serumk (6 commits)")[![andrex47](https://avatars.githubusercontent.com/u/30880910?v=4)](https://github.com/andrex47 "andrex47 (3 commits)")[![Mnikoei](https://avatars.githubusercontent.com/u/19962633?v=4)](https://github.com/Mnikoei "Mnikoei (1 commits)")[![agravelot](https://avatars.githubusercontent.com/u/13699253?v=4)](https://github.com/agravelot "agravelot (1 commits)")[![socieboy](https://avatars.githubusercontent.com/u/7442695?v=4)](https://github.com/socieboy "socieboy (1 commits)")[![alvarofelipems](https://avatars.githubusercontent.com/u/4182816?v=4)](https://github.com/alvarofelipems "alvarofelipems (1 commits)")[![gorka-ideable](https://avatars.githubusercontent.com/u/164047762?v=4)](https://github.com/gorka-ideable "gorka-ideable (1 commits)")[![kresnasatya](https://avatars.githubusercontent.com/u/11099186?v=4)](https://github.com/kresnasatya "kresnasatya (1 commits)")[![MartinCamen](https://avatars.githubusercontent.com/u/8720813?v=4)](https://github.com/MartinCamen "MartinCamen (1 commits)")

---

Tags

jwtlaravelAuthenticationkeycloak

### Embed Badge

![Health badge](/badges/slowcheetah-laravel-keycloak-web-guard/health.svg)

```
[![Health](https://phpackages.com/badges/slowcheetah-laravel-keycloak-web-guard/health.svg)](https://phpackages.com/packages/slowcheetah-laravel-keycloak-web-guard)
```

###  Alternatives

[vizir/laravel-keycloak-web-guard

Simple Keycloak Guard to Laravel Web Routes

166574.1k](/packages/vizir-laravel-keycloak-web-guard)[benbjurstrom/cognito-jwt-guard

A laravel auth guard for JSON Web Tokens issued by Amazon AWS Cognito

1113.1k](/packages/benbjurstrom-cognito-jwt-guard)

PHPackages © 2026

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