bigpoint/slim-bootstrap3

These classes provide a simple way to bootstrap a slim v3 application with authentication.

2.0.1 2019-11-14 09:58 UTC

README

These classes provide a simple way to bootstrap a slim v3 application with authentication.

It is an abstraction of the Slim Framework v3 and handles some stuff like output generation in different formats and authentication / acl handling.

Installation

slim-bootstrap3 is available via packagist:

composer require bigpoint/slim-bootstrap3

Webserver configuration

In order to configure your webserver to pass all requests in a proper way to the slim application please read the Web Server section of the slim documentation.

How to implement manually

In order to create a REST API based on this framework you need a structure similar to the following in your project:

├── composer.json
├── config
│   └── application.json
├── include
│   └── DummyApi
│       └── Endpoint
│           └── V1
│               ├── EndpointA.php
│               └── EndpointB.php
└── www
    └── index.php

config/application.json

This file holds the main configuration for the implementation of the framework as a JSON. This file doesn't have to be at this location, it is just the default location. If you change it you have to adapt the example of the www/index.php that is shown later.

The following keys are possible but all optional (shown here with the default values):

{
  "displayErrorDetails": false,
  "cacheDuration": 900
}

The cacheDuration defines the interval (in seconds) used for the cache expire headers of the response (default: 900).

If the displayErrorDetails flag is set to true the slim framework will print out a stack trace if an error occurs. Otherwise it will just show a "500 Internal Server Error" (default: false).

the include/ folder

This folder should contain your endpoint implementation. Read below about how to define an endpoint.

www/index.php

This file is the main entry point for the application. Here is a minimum example how this file should look like:

<?php
require(__DIR__ . '/../vendor/autoload.php');

$endpoints = [
    [
        'type'           => SlimBootstrap\Bootstrap::HTTP_METHOD_GET,
        'route'          => '/dummy/test/{id:[0-9]+}',
        'name'           => 'dummy',
        'instance'       => new DummyApi\Endpoint\V1\Dummy(),
        'authentication' => false,
    ],
];

$slimBootstrap = new \SlimBootstrap\Bootstrap();
$slimBootstrap->run($endpoints);

Logging

If you want to enable logging for the API, you can inject an instance of \Monolog\Logger into the framework by calling the setLogger() on the instance of the \SlimBootstrap\Bootstrap object (this method is chainable):

-$slimBootstrap->run($endpoints);
+$slimBootstrap->setLogger(new \Monolog\Logger('dummyApi'))->run($endpoints);

Create Endpoints

An endpoint is a PHP class that has to implement at least one of the \SlimBootstrap\Endpoint\* interfaces depending on what HTTP method it should support (see below for more details). All endpoints have to return a PHP array with the data they want to output in the end. The framework will then take care of rendering this in the correct output format.

Supported HTTP methods

At the moment the framework supports the following HTTP methods:

  • DELETE
  • GET
  • POST
  • PUT

For each of these methods the framework supplies an interface for the endpoints under \SlimBootstrap\Endpoint\.

Registering endpoints to the framework

The written endpoints have to be registered to the framework and the underlying Slim instance in order to be accessible. This is done by passing an array to the run() on the \SlimBootstrap\Bootstrap instance. The framework is using the basic form of slim to register a route and bind an endpoint to the route. However at the moment slim-bootstrap3 doesn't allow grouping of endpoints. The array has to have the following structure:

$endpoints = [
    [
        'type'     => SlimBootstrap\Bootstrap::HTTP_METHOD_GET,
        'route'    => '/dummy/test/{id:[0-9]+}',
        'name'     => 'dummy',
        'instance' => new DummyApi\Endpoint\Dummy(),
    ],
    [
        'type'           => SlimBootstrap\Bootstrap::HTTP_METHOD_GET,
        'route'          => '/dummy/test/{id:[0-9]+}',
        'name'           => 'dummy-other',
        'instance'       => new DummyApi\Endpoint\DummyOther(),
        'authentication' => false
    ],
];
parameter type required default description
type string yes should be one of the \SlimBootstrap\Bootstrap::HTTP_METHOD_* constants to define the method you want to match
route string yes pattern for the route to match. See Route documentation of slim for details
name string yes name to identify this (group of) endpoint(s). Used in the ACL handling
instance SlimBootstrap\Endpoint yes Instance of endpoint class. Has to match the Endpoint interface corresponding to the $type used
authentication bool no true It is possible to disable authentication for only one specific endpoint. This flag is used for that

Response output

Slim-bootstrap3 has the possibility to support multiple output formats, which can be requested via header attribute "Accept". These are the formats that are currently supported:

  • application/json (default)

Authentication

When authentication is enabled, you have to add some more entries to your configuration file depending on the authentication method you are using.

Changes for authentication

Changes to config/application.json

You have to add a "acl" key to the application.json config, which defines accessible endpoints for a clientId.

{
    ...
    "acl": {
        "roles": {
            "role_dummy": {
                "dummy": true
            }
        },
        "access": {
            "myDummyClientId": "role_dummy"
        }
    }
    ...
}

This is mapping the clientId "myDummyClientId" to the role "role_dummy" which has access to the "dummy" endpoint.

OAuth

You have to add the url parameter access_token to api calls with an access token given from your oauth server. The authentication logic validates this access token against the configured oauth server via its /me endpoint. Next the collected clientId from /me endpoint is going to be validated against requested endpoint and configured ACL. If all is fine, access is granted to requester. Otherwise request is aborted with an 401 or 403 HTTP status code.

Additional values for config/application.json

 {
  ...
  "oauth": {
    "authenticationUrl": "https://myserver.com/me?access_token=",
    "clientIdField": "entity_id"
  },
  ...
}

The clientIdField value is optional to define in which field of the result of the Oauth response the clientId can be found. The default is "entity_id".

Changes to www/index.php

-    $slimBootstrap->run($endpoints);
+    $slimBootstrap->setAuthentication('oauth')->run($endpoints);

JWT

You have to add the JWT as an authorization bearer header to the request of the API. The framework will verify and validate the JWT with the public key from the JWT provider provided in jwt.publicKey. For the validation all fields from the config's jwt.claims block have to match with the JWT.

After that the framework will extract the clientId from the claim "name" and the role from the "role" claim. Next the collected clientId and role are going to be validated against requested endpoint and configured ACL. If all is fine, access is granted to requester. Otherwise request is aborted with an 401 or 403 HTTP status code.

Additional values for config/application.json

{
  ...
  "jwt": {
    "publicKey": "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAElAfxdt6MZxXc4TsZROhm8QPnoDm5\nILVK9el6kU9xd+3Pnb3yOBsLTnuX9/x2c8HIQIoxEs8IlreBQndy3CvRJQ==\n-----END PUBLIC KEY-----\n",
    "encryption": "ES256",
    "clientDataClaims": {
      "clientId": "name",
      "role": "role"
    },
    "claims": {
      "issuer": "sombra_development"
    }
  },
  ...
}

The jwt.clientDataClaims option key is optional and defines in which claims the clientId and role of the user can be found. If this key is not specified the fields are "name" for the clientId and "role" for the role. The jwt.encrpytion option key is optional and defines which encryption was used to sign the token. If this key is not present, the fallback "ES256" is used. This library supports all algorithms that lcobucci/jwt version 3.* supports.

Changes to www/index.php

-    $slimBootstrap->run($endpoints);
+    $slimBootstrap->setAuthentication('jwt')->run($endpoints);

Sombra

This is an JWT provider specifically written to work with a Sombra instance. It does the same as the normal JWT provider but it reads the public key from the provided jwt.sombraUrl host.

Custom Authentication

If you want, you can define your own authentication class which for example reads from a database. If you want to do this you have to implement the Authentication interface. This implementation can bet used as parameter for the setAuthentication call to the \SlimBootstrap\Bootstrap objecct instead of the string.

License & Authors

Copyright:: 2016 Bigpoint GmbH

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.