PHPackages                             elbanyaoui/slim-jwt-auth - 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. [HTTP &amp; Networking](/categories/http)
4. /
5. elbanyaoui/slim-jwt-auth

ActiveLibrary[HTTP &amp; Networking](/categories/http)

elbanyaoui/slim-jwt-auth
========================

PSR-7 JWT Authentication Middleware a customized version created by elbanyaoui based on tuupola/slim-jwt-auth project

2.3.4(8y ago)0391MITPHPPHP ^5.5 || ^7.0

Since Apr 12Pushed 7y ago1 watchersCompare

[ Source](https://github.com/elbanyaoui/slim-jwt-auth)[ Packagist](https://packagist.org/packages/elbanyaoui/slim-jwt-auth)[ Docs](https://github.com/elbanyaoui/slim-jwt-auth)[ RSS](/packages/elbanyaoui-slim-jwt-auth/feed)WikiDiscussions 2.x Synced yesterday

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

PSR-7 JWT Authentication Middleware
===================================

[](#psr-7-jwt-authentication-middleware)

[![Latest Version](https://camo.githubusercontent.com/7a9e7ef1c60ec2d64b94059ee9597d8e46b30834af7f5ed0607b846797268038/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f747575706f6c612f736c696d2d6a77742d617574682e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/tuupola/slim-jwt-auth)[![Packagist](https://camo.githubusercontent.com/b19196d83170a956af0b2b6410bcb580c08da87f1062d3017c80436a55b5a97b/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f646d2f747575706f6c612f736c696d2d6a77742d617574682e737667)](https://packagist.org/packages/tuupola/slim-jwt-auth)[![Software License](https://camo.githubusercontent.com/55c0218c8f8009f06ad4ddae837ddd05301481fcf0dff8e0ed9dadda8780713e/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6c6963656e73652d4d49542d627269676874677265656e2e7376673f7374796c653d666c61742d737175617265)](LICENSE.md)[![Build Status](https://camo.githubusercontent.com/1853bb76f2c0e8509cc7ccce10e14f60b60de14220bc0ad17bd2ddadecb264b1/68747470733a2f2f696d672e736869656c64732e696f2f7472617669732f747575706f6c612f736c696d2d6a77742d617574682f6d61737465722e7376673f7374796c653d666c61742d737175617265)](https://travis-ci.org/tuupola/slim-jwt-auth)[![Coverage](https://camo.githubusercontent.com/343830a5f678d13793b4699cab1461a935572664acc989a7c7d7a18b889098e8/687474703a2f2f696d672e736869656c64732e696f2f636f6465636f762f632f6769746875622f747575706f6c612f736c696d2d6a77742d617574682f322e782e7376673f7374796c653d666c61742d737175617265)](https://codecov.io/github/tuupola/slim-jwt-auth/branch/2.x)

This middleware implements JSON Web Token Authentication. It was originally developed for Slim but can be used with any framework using PSR-7 style middlewares. It has been tested with [Slim Framework](http://www.slimframework.com/) and [Zend Expressive](https://zendframework.github.io/zend-expressive/).

Middleware does **not** implement OAuth 2.0 authorization server nor does it provide ways to generate, issue or store authentication tokens. It only parses and authenticates a token when passed via header or cookie. This is useful for example when you want to use [JSON Web Tokens as API keys](https://auth0.com/blog/2014/12/02/using-json-web-tokens-as-api-keys/).

For example implementation see [Slim API Skeleton](https://github.com/tuupola/slim-api-skeleton).

Install
-------

[](#install)

Install latest version using [composer](https://getcomposer.org/).

```
$ composer require elbanyaoui/slim-jwt-auth
```

If using Apache add the following to the `.htaccess` file. Otherwise PHP wont have access to `Authorization: Bearer` header.

```
RewriteRule .* - [env=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
```

Usage
-----

[](#usage)

Configuration options are passed as an array. The only mandatory parameter is `secret` which is used for verifying then token signature. Note again that `secret` is not the token. It is the secret you use to sign the token.

For simplicity's sake examples show `secret` hardcoded in code. In real life you should store it somewhere else. Good option is environment variable. You can use [dotenv](https://github.com/vlucas/phpdotenv) or something similar for development. Examples assume you are using Slim Framework.

```
$app = new \Slim\App();

$app->add(new \Slim\Middleware\JwtAuthentication([
    "secret" => "supersecretkeyyoushouldnotcommittogithub"
]));
```

An example where your secret is stored as an environment variable:

```
$app = new \Slim\App();

$app->add(new \Slim\Middleware\JwtAuthentication([
    "secret" => getenv("JWT_SECRET")
]));
```

When a request is made, the middleware tries to validate and decode the token. If a token is not found or there is an error when validating and decoding it, the server will respond with `401 Unauthorized`.

Validation errors are triggered when the token has been tampered with or the token has expired. For all possible validation errors, see [JWT library ](https://github.com/firebase/php-jwt/blob/master/src/JWT.php#L60-L123) source.

Optional parameters
-------------------

[](#optional-parameters)

### Path

[](#path)

The optional `path` parameter allows you to specify the protected part of your website. It can be either a string or an array. You do not need to specify each URL. Instead think of `path` setting as a folder. In the example below everything starting with `/api` will be authenticated.

```
$app = new \Slim\App();

$app->add(new \Slim\Middleware\JwtAuthentication([
    "path" => "/api", /* or ["/api", "/admin"] */
    "secret" => "supersecretkeyyoushouldnotcommittogithub"
]));
```

### Passthrough

[](#passthrough)

With optional `passthrough` parameter you can make exceptions to `path` parameter. In the example below everything starting with `/api` and `/admin` will be authenticated with the exception of `/api/token` and `/admin/ping` which will not be authenticated.

```
$app = new \Slim\App();

$app->add(new \Slim\Middleware\JwtAuthentication([
    "path" => ["/api", "/admin"],
    "passthrough" => ["/api/token", "/admin/ping"],
    "secret" => "supersecretkeyyoushouldnotcommittogithub"
]));
```

### Passthrough by request and method

[](#passthrough-by-request-and-method)

```
$app = new \Slim\App();

$app->add(new \Slim\Middleware\JwtAuthentication([
    "path" => ["/api", "/admin"],
    "passthrough" => ["/api/token", "/admin/ping"],
    "secret" => "supersecretkeyyoushouldnotcommittogithub",
	"rules" => [
        new\Slim\Middleware\JwtAuthentication\RequestMethodRule([
            "passthrough" => ["OPTIONS"]
        ]),
        new\Slim\Middleware\JwtAuthentication\RequestMethodPathRule([
            "passthrough" => [
                "GET"=>"/items/"
            ]
        ]),
        new\Slim\Middleware\JwtAuthentication\RequestMethodPathRule([
            "passthrough" => [
                "GET"=>"/categories/"
            ]
        ])
    ],
]));
```

### Environment

[](#environment)

By default middleware tries to find the token from `HTTP_AUTHORIZATION` and `REDIRECT_HTTP_AUTHORIZATION` environments. You can change this using `environment` parameter. Note that usually you should also use matching `header` parameter.

```
$app = new \Slim\App();

$app->add(new \Slim\Middleware\JwtAuthentication([
    "environment" => ["HTTP_BRAWNDO", "REDIRECT_HTTP_BRAWNDO"],
    "header" => "Brawndo",
    "secret" => "supersecretkeyyoushouldnotcommittogithub"
]));
```

### Header

[](#header)

If token is not found from environment the middleware tries to find it from `Authorization` header. You can change cookie name using `header` parameter. Note that usually you should also use matching `environment` parameter.

```
$app = new \Slim\App();

$app->add(new \Slim\Middleware\JwtAuthentication([
    "environment" => "HTTP_X_TOKEN",
    "header" => "X-Token",
    "secret" => "supersecretkeyyoushouldnotcommittogithub"
]));
```

### Cookie

[](#cookie)

If token is not found from neither environment or header, the middleware tries to find it from cookie named `token`. You can change cookie name using `cookie` parameter.

```
$app = new \Slim\App();

$app->add(new \Slim\Middleware\JwtAuthentication([
    "cookie" => "nekot",
    "secret" => "supersecretkeyyoushouldnotcommittogithub"
]));
```

### Regexp

[](#regexp)

By default the middleware assumes the value of the header is in `Bearer ` format. You can change this behaviour with `regexp` parameter. For example if you have custom header such as `X-Token: ` you should pass both header and regexp parameters.

```
$app = new \Slim\App();

$app->add(new \Slim\Middleware\JwtAuthentication([
    "header" => "X-Token",
    "regexp" => "/(.*)/",
    "secret" => "supersecretkeyyoushouldnotcommittogithub"
]));
```

### Algorithm

[](#algorithm)

You can set supported algorithms via `algorithm` parameter. This can be either string or array of strings. Default value is `["HS256", "HS512", "HS384"]`. Supported algorithms are `HS256`, `HS384`, `HS512` and `RS256`. Note that enabling both `HS256` and `RS256` is a [security risk](https://auth0.com/blog/2015/03/31/critical-vulnerabilities-in-json-web-token-libraries/).

```
$app = new \Slim\App();

$app->add(new \Slim\Middleware\JwtAuthentication([
    "secret" => "supersecretkeyyoushouldnotcommittogithub",
    "algorithm" => ["HS256", "HS384"]
]));
```

### Attribute

[](#attribute)

When the token is decoded successfully and authentication succees the contents of decoded token as saved as `token` attribute to the `$request` object. You can change this with. `attribute` parameter. Set to `null` or `false` to disable this behavour

```
$app = new \Slim\App();

$app->add(new \Slim\Middleware\JwtAuthentication([
    "attribute" => "jwt",
    "secret" => "supersecretkeyyoushouldnotcommittogithub"
]));

/* ... */

$decoded = $request->getAttribute("jwt");
```

### Logger

[](#logger)

The optional `logger` parameter allows you to pass in a PSR-3 compatible logger to help with debugging or other application logging needs.

```
use Monolog\Logger;
use Monolog\Handler\RotatingFileHandler;

$app = new \Slim\App();

$logger = new Logger("slim");
$rotating = new RotatingFileHandler(__DIR__ . "/logs/slim.log", 0, Logger::DEBUG);
$logger->pushHandler($rotating);

$app->add(new \Slim\Middleware\JwtAuthentication([
    "path" => "/api",
    "logger" => $logger,
    "secret" => "supersecretkeyyoushouldnotcommittogithub"
]));
```

### Callback

[](#callback)

Callback is called only when authentication succeeds. It receives decoded token in arguments. If callback returns boolean `false` authentication is forced to be failed.

You can also use callback for storing the value of decoded token for later use.

```
$app = new \Slim\App();

$container = $app->getContainer();

$container["jwt"] = function ($container) {
    return new StdClass;
};

$app->add(new \Slim\Middleware\JwtAuthentication([
    "secret" => "supersecretkeyyoushouldnotcommittogithub",
    "callback" => function ($request, $response, $arguments) use ($container) {
        $container["jwt"] = $arguments["decoded"];
    }
]));
```

### Error

[](#error)

Error is called when authentication fails. It receives last error message in arguments.

```
$app = new \Slim\App();

$app->add(new \Slim\Middleware\JwtAuthentication([
    "secret" => "supersecretkeyyoushouldnotcommittogithub",
    "error" => function ($request, $response, $arguments) {
        $data["status"] = "error";
        $data["message"] = $arguments["message"];
        return $response
            ->withHeader("Content-Type", "application/json")
            ->write(json_encode($data, JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT));
    }
]));
```

### Rules

[](#rules)

The optional `rules` parameter allows you to pass in rules which define whether the request should be authenticated or not. A rule is a callable which receives the request as parameter. If any of the rules returns boolean `false` the request will not be authenticated.

By default middleware configuration looks like this. All paths are authenticated with all request methods except `OPTIONS`.

```
$app = new \Slim\App();

$app->add(new \Slim\Middleware\JwtAuthentication([
    "rules" => [
        new \Slim\Middleware\JwtAuthentication\RequestPathRule([
            "path" => "/",
            "passthrough" => []
        ]),
        new \Slim\Middleware\JwtAuthentication\RequestMethodRule([
            "passthrough" => ["OPTIONS"]
        ])
    ]
]));
```

RequestPathRule contains both a `path` parameter and a `passthrough` parameter. Latter contains paths which should not be authenticated. RequestMethodRule contains `passthrough` parameter of request methods which also should not be authenticated. Think of `passthrough` as a whitelist.

Example use case for this is an API. Token can be retrieved via [HTTP Basic Auth](https://github.com/tuupola/slim-basic-auth) protected address. There also is an unprotected url for pinging. Rest of the API is protected by the JWT middleware.

```
$app = new \Slim\App();

$app->add(new \Slim\Middleware\JwtAuthentication([
    "logger" => $logger,
    "secret" => "supersecretkeyyoushouldnotcommittogithub",
    "rules" => [
        new RequestPathRule([
            "path" => "/api",
            "passthrough" => ["/api/token", "/api/ping"]
        ]),
        new \Slim\Middleware\JwtAuthentication\RequestMethodRule([
            "passthrough" => ["OPTIONS"]
        ])
    ]
]));

$app->add(new \Slim\Middleware\HttpBasicAuthentication([
    "path" => "/api/token",
    "users" => [
        "user" => "password"
    ]
]));

$app->post("/token", function () {
  /* Here generate and return JWT to the client. */
});
```

Security
--------

[](#security)

JSON Web Tokens are essentially passwords. You should treat them as such and you should always use HTTPS. If the middleware detects insecure usage over HTTP it will throw a `RuntimeException`. This rule is relaxed for requests on localhost. To allow insecure usage you must enable it manually by setting `secure` to `false`.

```
$app->add(new \Slim\Middleware\JwtAuthentication([
    "secure" => false,
    "secret" => "supersecretkeyyoushouldnotcommittogithub"
]));
```

Alternatively you can list your development host to have relaxed security.

```
$app->add(new \Slim\Middleware\JwtAuthentication([
    "secure" => true,
    "relaxed" => ["localhost", "dev.example.com"],
    "secret" => "supersecretkeyyoushouldnotcommittogithub"
]));
```

Authorization
-------------

[](#authorization)

By default middleware only authenticates. This is not very interesting. Beauty of JWT is you can pass extra data in the token. This data can include for example scope which can be used for authorization.

**It is up to you to implement how token data is stored or possible authorization implemented.**

Let assume you have token which includes data for scope. In middleware callback you store the decoded token data to `$app->jwt` and later use it for authorization.

```
[
    "iat" => "1428819941",
    "exp" => "1744352741",
    "scope" => ["read", "write", "delete"]
]
```

```
$app = new \Slim\App();

$container = $app->getContainer();

$container["jwt"] = function ($container) {
    return new StdClass;
};

$app->add(new \Slim\Middleware\JwtAuthentication([
    "secret" => "supersecretkeyyoushouldnotcommittogithub",
    "callback" => function ($request, $response, $arguments) use ($container) {
        $container["jwt"] = $arguments["decoded"];
    }
]));

$app->delete("/item/{id}", function ($request, $response, $arguments) {
    if (in_array("delete", $this->jwt->scope)) {
        /* Code for deleting item */
    } else {
        /* No scope so respond with 401 Unauthorized */
        return $response->withStatus(401);
    }
});
```

Testing
-------

[](#testing)

You can run individual tests either manually...

```
$ composer phplint
$ composer phpcs
$ composer phpunit
```

... or automatically on every code change. You will need [entr](http://entrproject.org/) for this to work.

```
$ composer watch
```

Contributing
------------

[](#contributing)

Please see [CONTRIBUTING](CONTRIBUTING.md) for details.

Security
--------

[](#security-1)

If you discover any security related issues, please email  instead of using the issue tracker.

License
-------

[](#license)

The MIT License (MIT). Please see [License File](LICENSE.md) for more information.

###  Health Score

30

—

LowBetter than 64% of packages

Maintenance20

Infrequent updates — may be unmaintained

Popularity8

Limited adoption so far

Community14

Small or concentrated contributor base

Maturity68

Established project with proven stability

 Bus Factor1

Top contributor holds 94.7% 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 ~42 days

Recently: every ~67 days

Total

27

Last Release

2953d ago

Major Versions

1.0.1 → 2.0.02015-10-01

1.0.2 → 2.0.22015-12-10

1.0.3 → 2.3.22017-02-27

1.x-dev → 2.3.32017-07-12

2.3.3 → 3.0.0-rc.12017-07-17

PHP version history (4 changes)0.1.0PHP &gt;=5.3.0

2.0.0PHP &gt;=5.4.0

2.3.1PHP ^5.5 || ^7.0

1.0.3PHP ^5.3

### Community

Maintainers

![](https://www.gravatar.com/avatar/9347bc0fd5a2c4de2e0f3e9efbeb2200b8e1360f1f5ae7457f5c4b8bdc0cf6c5?d=identicon)[elbanyaoui](/maintainers/elbanyaoui)

---

Top Contributors

[![tuupola](https://avatars.githubusercontent.com/u/21913?v=4)](https://github.com/tuupola "tuupola (144 commits)")[![elbanyaoui](https://avatars.githubusercontent.com/u/10333690?v=4)](https://github.com/elbanyaoui "elbanyaoui (4 commits)")[![BafS](https://avatars.githubusercontent.com/u/588205?v=4)](https://github.com/BafS "BafS (1 commits)")[![dakujem](https://avatars.githubusercontent.com/u/443067?v=4)](https://github.com/dakujem "dakujem (1 commits)")[![orx0r](https://avatars.githubusercontent.com/u/2333215?v=4)](https://github.com/orx0r "orx0r (1 commits)")[![xu42](https://avatars.githubusercontent.com/u/12060792?v=4)](https://github.com/xu42 "xu42 (1 commits)")

---

Tags

psr-7jwtjsonmiddlewareauth

###  Code Quality

TestsPHPUnit

Code StylePHP\_CodeSniffer

### Embed Badge

![Health badge](/badges/elbanyaoui-slim-jwt-auth/health.svg)

```
[![Health](https://phpackages.com/badges/elbanyaoui-slim-jwt-auth/health.svg)](https://phpackages.com/packages/elbanyaoui-slim-jwt-auth)
```

###  Alternatives

[jimtools/jwt-auth

PSR-15 JWT Authentication middleware, A replacement for tuupola/slim-jwt-auth

20142.3k3](/packages/jimtools-jwt-auth)[shopify/shopify-api

Shopify API Library for PHP

4634.8M16](/packages/shopify-shopify-api)[tuupola/slim-basic-auth

PSR-7 and PSR-15 HTTP Basic Authentication Middleware

4442.0M26](/packages/tuupola-slim-basic-auth)[jasny/auth

Authentication, authorization and access control for Slim Framework and other PHP micro-frameworks

11816.4k1](/packages/jasny-auth)[phpro/http-tools

HTTP tools for developing more consistent HTTP implementations.

28137.8k](/packages/phpro-http-tools)[mezzio/mezzio-authentication-oauth2

OAuth2 (server) authentication middleware for Mezzio and PSR-7 applications.

28483.0k2](/packages/mezzio-mezzio-authentication-oauth2)

PHPackages © 2026

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