PHPackages                             tuupola/branca-middleware - 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. tuupola/branca-middleware

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

tuupola/branca-middleware
=========================

PSR-7 and PSR-15 Branca Authentication Middleware

0.7.0(5y ago)95.6k1[2 issues](https://github.com/tuupola/branca-middleware/issues)MITPHPPHP ^7.2|^8.0CI failing

Since Aug 7Pushed 4y ago3 watchersCompare

[ Source](https://github.com/tuupola/branca-middleware)[ Packagist](https://packagist.org/packages/tuupola/branca-middleware)[ Docs](https://github.com/tuupola/branca-middleware)[ GitHub Sponsors](https://github.com/tuupola)[ RSS](/packages/tuupola-branca-middleware/feed)WikiDiscussions master Synced 2w ago

READMEChangelogDependencies (12)Versions (13)Used By (0)

PSR-7 and PSR-15 Branca Authentication Middleware
=================================================

[](#psr-7-and-psr-15-branca-authentication-middleware)

[![Latest Version](https://camo.githubusercontent.com/6eac4a11290f0ec158fae5afceba40fe4ef302e91c7aaaab77b1b4c4d3df375b/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f747575706f6c612f6272616e63612d6d6964646c65776172652e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/tuupola/branca-middleware)[![Software License](https://camo.githubusercontent.com/55c0218c8f8009f06ad4ddae837ddd05301481fcf0dff8e0ed9dadda8780713e/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6c6963656e73652d4d49542d627269676874677265656e2e7376673f7374796c653d666c61742d737175617265)](LICENSE)[![Build Status](https://camo.githubusercontent.com/54b10e111abb8427b848f5fba8a87c89e7fb0443ba22cf26f701a456853a9d9a/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f776f726b666c6f772f7374617475732f747575706f6c612f6272616e63612d6d6964646c65776172652f54657374732f6d61737465723f7374796c653d666c61742d737175617265)](https://github.com/tuupola/branca-middleware/actions)[![Coverage](https://camo.githubusercontent.com/2f53ce4717a3e34dffe4aef462b2e38cbe6ee24e4439e310bcef2361c7752c1e/68747470733a2f2f696d672e736869656c64732e696f2f636f6465636f762f632f6769746875622f747575706f6c612f6272616e63612d6d6964646c65776172652f6d61737465722e7376673f7374796c653d666c61742d737175617265)](https://codecov.io/github/tuupola/branca-middleware/branch/master)

This middleware implements [Branca token](https://github.com/tuupola/branca-spec) authentication. Branca is similar to JWT but more secure and has smaller token size. The middleware can be used with any framework using PSR-7 or PSR-15 style middlewares. It has been tested with [Slim Framework](http://www.slimframework.com/) and [Zend Expressive](https://zendframework.github.io/zend-expressive/).

You might also be interested in reading [Branca as an Alternative to JWT?](https://appelsiini.net/2017/branca-alternative-to-jwt/.)

This middleware does **not** implement OAuth authorization server nor does it provide ways to generate, issue or store the authentication tokens. It only parses and authenticates a token when passed via header or cookie.

Install
-------

[](#install)

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

```
$ composer require tuupola/branca-middleware
```

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 32 byte `secret` which is used for authenticating and encrypting 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->add(new Tuupola\Middleware\BrancaAuthentication([
    "secret" => "supersecretkeyyoushouldnotcommit"
]));
```

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

```
$app->add(new Tuupola\Middleware\BrancaAuthentication([
    "secret" => getenv("BRANCA_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 optionally if the token has expired.

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. If you do not define `path` all routes will be protected.

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

### Ignore

[](#ignore)

With optional `ignore` 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->add(new Tuupola\Middleware\BrancaAuthentication([
    "path" => ["/api", "/admin"],
    "ignore" => ["/api/token", "/admin/ping"],
    "secret" => "supersecretkeyyoushouldnotcommit"
]));
```

### TTL

[](#ttl)

Branca tokens have a creation timestamp embedded in the header. You can control how old token your application accepts with the `ttl` parameter.

```
$app->add(new Tuupola\Middleware\BrancaAuthentication([
    "ttl" => 3600, /* 60 minutes */
    "secret" => "supersecretkeyyoushouldnotcommit"
]));
```

### Header

[](#header)

By default middleware tries to find the token from `Authorization` header. You can change header name using the `header` parameter.

```
$app->add(new Tuupola\Middleware\BrancaAuthentication([
    "header" => "X-Token",
    "secret" => "supersecretkeyyoushouldnotcommit"
]));
```

### 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->add(new Tuupola\Middleware\BrancaAuthentication([
    "header" => "X-Token",
    "regexp" => "/(.*)/",
    "secret" => "supersecretkeyyoushouldnotcommit"
]));
```

### 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->add(new Tuupola\Middleware\BrancaAuthentication([
    "cookie" => "nekot",
    "secret" => "supersecretkeyyoushouldnotcommit"
]));
```

### 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 Tuupola\Middleware\BrancaAuthentication([
    "path" => "/api",
    "logger" => $logger,
    "secret" => "supersecretkeyyoushouldnotcommit"
]));
```

### Before

[](#before)

Before funcion is called only when authentication succeeds but before the next incoming middleware is called. You can use this to alter the request before passing it to the next incoming middleware in the stack. If it returns anything else than `Psr\Http\Message\RequestInterface` the return value will be ignored.

```
$app->add(new Tuupola\Middleware\BrancaAuthentication([
    "secret" => "supersecretkeyyoushouldnotcommit",
    "before" => function ($request, $arguments) {
        return $request->withAttribute("test", "test");
    }
]));
```

### After

[](#after)

After function is called only when authentication succeeds and after the incoming middleware stack has been called. You can use this to alter the response before passing it next outgoing middleware in the stack. If it returns anything else than `Psr\Http\Message\ResponseInterface` the return value will be ignored.

```
$app->add(new Tuupola\Middleware\BrancaAuthentication([
    "secret" => "supersecretkeyyoushouldnotcommit",
    "after" => function ($response, $arguments) {
        return $response->withHeader("X-Brawndo", "plants crave");
    }
]));
```

### Error

[](#error)

Error is called when authentication fails. It receives last error message in arguments. You can use this for example to return JSON formatted error responses.

```
$app->add(new Tuupola\Middleware\BrancaAuthentication([
    "secret" => "supersecretkeyyoushouldnotcommit",
    "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->add(new Tuupola\Middleware\BrancaAuthentication([
    "rules" => [
        new Tuupola\Middleware\BrancaAuthentication\RequestPathRule([
            "path" => "/",
            "ignore" => []
        ]),
        new Tuupola\Middleware\BrancaAuthentication\RequestMethodRule([
            "ignore" => ["OPTIONS"]
        ])
    ]
]));
```

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

99% of the cases you do not need to use the `rules` parameter. It is only provided for special cases when defaults do not suffice.

Security
--------

[](#security)

Branca 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 Tuupola\Middleware\BrancaAuthentication([
    "secure" => false,
    "secret" => "supersecretkeyyoushouldnotcommit"
]));
```

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

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

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

[](#authorization)

By default middleware only authenticates. This is not very interesting by itself. Beauty of Branca is that 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 JSON encoded payload which includes requested scope and uid. Using the `before` callback you can inject the unencoded payload to the request object.

```
[
    "uid" => 123,
    "scope" => ["read", "write", "delete"]
]
```

```
$app->add(new Tuupola\Middleware\BrancaAuthentication([
    "secret" => "supersecretkeyyoushouldnotcommit",
    "before" => function ($request, $arguments) {
        $payload = json_decode($arguments["payload"], true);
        return $request->withAttribute("token", $payload);
    }
]));

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

Testing
-------

[](#testing)

You can run tests either manually or automatically on every code change. Automatic tests require [entr](http://entrproject.org/) to work.

```
$ make test
```

```
$ brew install entr
$ make 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](LICENSEd) for more information.

###  Health Score

33

—

LowBetter than 72% of packages

Maintenance16

Infrequent updates — may be unmaintained

Popularity26

Limited adoption so far

Community11

Small or concentrated contributor base

Maturity65

Established project with proven stability

 Bus Factor1

Top contributor holds 98.9% 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 ~117 days

Recently: every ~203 days

Total

11

Last Release

2069d ago

PHP version history (4 changes)0.1.0PHP ^5.6 || ^7.0

0.2.0PHP ^7.0

0.5.0PHP ^7.1

0.7.0PHP ^7.2|^8.0

### Community

Maintainers

![](https://www.gravatar.com/avatar/3325405a7d8a43bc40dd0e760a4b7f268fba32a7150cf0327f64f13d1661df0b?d=identicon)[tuupola](/maintainers/tuupola)

---

Top Contributors

[![tuupola](https://avatars.githubusercontent.com/u/21913?v=4)](https://github.com/tuupola "tuupola (90 commits)")[![ADmad](https://avatars.githubusercontent.com/u/142658?v=4)](https://github.com/ADmad "ADmad (1 commits)")

---

Tags

apijwttoken-authenticationxchacha20-poly1305psr-7jwtmiddlewarepsr-17authpsr-15branca

###  Code Quality

TestsPHPUnit

Static AnalysisPHPStan

Code StylePHP\_CodeSniffer

Type Coverage Yes

### Embed Badge

![Health badge](/badges/tuupola-branca-middleware/health.svg)

```
[![Health](https://phpackages.com/badges/tuupola-branca-middleware/health.svg)](https://phpackages.com/packages/tuupola-branca-middleware)
```

###  Alternatives

[cakephp/cakephp

The CakePHP framework

8.8k19.1M1.7k](/packages/cakephp-cakephp)[laminas/laminas-stratigility

PSR-7 middleware foundation for building and dispatching middleware pipelines

577.0M95](/packages/laminas-laminas-stratigility)[mezzio/mezzio

PSR-15 Middleware Microframework

3913.8M120](/packages/mezzio-mezzio)[jimtools/jwt-auth

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

21171.6k4](/packages/jimtools-jwt-auth)[tuupola/cors-middleware

PSR-7 and PSR-15 CORS middleware

1331.9M29](/packages/tuupola-cors-middleware)[middlewares/utils

Common utils for PSR-15 middleware packages

503.6M94](/packages/middlewares-utils)

PHPackages © 2026

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