bigpoint / slim-bootstrap3
These classes provide a simple way to bootstrap a slim v3 application with authentication.
Requires
- php: >=7.0
- ext-json: *
- bigpoint/http-caller-php: 2.*
- monolog/monolog: 3.*
- slim/http-cache: 0.*
- slim/slim: 3.*
Requires (Dev)
- ext-gmp: *
- lcobucci/clock: 3.*
- lcobucci/jwt: 5.*
- mdanter/ecc: 1.*
- phpunit/phpunit: 5.*
Suggests
- ext-gmp: needed for JWT support
- lcobucci/jwt: needed for JWT support (^3.4.0)
- mdanter/ecc: needed for JWT support (0.3.*)
Conflicts
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 ], ];
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. The token fields iat
(issued at), nbf
(not valid before) and exp
(expiration time) are
validated by default.
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.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.
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.claims
settings are used to validate the content of a token. Following constrains values from lcobucci/jwt are supported:
audience
- Lcobucci\JWT\Validation\Constraint\PermittedForissuer
- Lcobucci\JWT\Validation\Constraint\IssuedBy
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
- Authors:: Peter Ahrens (pahrens@bigpoint.net), Andreas Schleifer (aschleifer@bigpoint.net), Hendrik Meyer (hmeyer@bigpoint.net)
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.