| @ -1,2 +1,22 @@ | |||||
| # Gear JWT | |||||
| # Gear/Auth | |||||
| ```php | |||||
| // routes that are ignored by auth | |||||
| $routes = array( | |||||
| '/', | |||||
| ); | |||||
| $app->register('auth', 'Gear\Middleware\AuthMiddleware', array($routes)); | |||||
| // adding jwtHelper | |||||
| $options = array( | |||||
| env('JWT_SECRET'), | |||||
| env('JWT_URL'), | |||||
| env('JWT_EXPIRED_AT'), | |||||
| ); | |||||
| $app->register('jwtHelper', 'Gear\Helpers\JwtHelper', $options); | |||||
| // adding filters | |||||
| $app->before('start', array(new Gear\Filters\AuthFilter, 'before')); | |||||
| ``` | |||||
| @ -0,0 +1,17 @@ | |||||
| { | |||||
| "name": "gear/auth", | |||||
| "type": "libary", | |||||
| "license": "MIT", | |||||
| "authors": [ | |||||
| { "name": "Björn Hase", "email": "me@tentakelfabrik.de" } | |||||
| ], | |||||
| "require": { | |||||
| "php": "^7.0", | |||||
| "firebase/php-jwt": "^5.0" | |||||
| }, | |||||
| "autoload": { | |||||
| "psr-4": { | |||||
| "Gear\\": "src/" | |||||
| } | |||||
| } | |||||
| } | |||||
| @ -0,0 +1,29 @@ | |||||
| <?php | |||||
| namespace Gear\Auth\Filters; | |||||
| use Gear\FlightAbstract; | |||||
| /** | |||||
| * Filter for Auth | |||||
| * | |||||
| * @author Björn Hase | |||||
| * @license http://opensource.org/licenses/MIT The MIT License | |||||
| * @link https://gitlab.tentakelfabrik.de/gear/gear-jwt | |||||
| */ | |||||
| class AuthFilter extends FlightAbstract | |||||
| { | |||||
| /** | |||||
| * if result of auth is false halt app and set response to 403 | |||||
| * | |||||
| * | |||||
| * @param array $params | |||||
| * @param array $output | |||||
| */ | |||||
| public function before(&$params, &$output) | |||||
| { | |||||
| if (!$this->app->auth()->attempt()) { | |||||
| $this->app->halt(403, 'Access Denied!'); | |||||
| } | |||||
| } | |||||
| } | |||||
| @ -0,0 +1,67 @@ | |||||
| <?php | |||||
| namespace Gear\Auth; | |||||
| use Firebase\JWT\JWT; | |||||
| /** | |||||
| * Wrapper for Firebase JWT | |||||
| * | |||||
| * | |||||
| * | |||||
| * @author Björn Hase | |||||
| * @license http://opensource.org/licenses/MIT The MIT License | |||||
| * @link https://gitlab.tentakelfabrik.de/gear/gear-jwt | |||||
| */ | |||||
| class Jwt | |||||
| { | |||||
| /** | |||||
| * | |||||
| * @param string $secret | |||||
| * @param string $url | |||||
| * @param string $expiredAt | |||||
| */ | |||||
| public function __construct($secret, $url, $expiredAt) | |||||
| { | |||||
| $this->secret = $secret; | |||||
| $this->url = $url; | |||||
| $this->expiredAt = $expiredAt; | |||||
| } | |||||
| /** | |||||
| * encode JWT, adding Data | |||||
| * | |||||
| * @param array $data | |||||
| * @return object | |||||
| */ | |||||
| public function encode($data = NULL) | |||||
| { | |||||
| // current time | |||||
| $time = time(); | |||||
| // create token | |||||
| $token = array( | |||||
| 'iss' => $this->url, | |||||
| 'iat' => $time, | |||||
| 'nbf' => $time, | |||||
| 'exp' => $time + $this->expiredAt | |||||
| ); | |||||
| if ($data) { | |||||
| $token['data'] = $data; | |||||
| } | |||||
| return JWT::encode($token, $this->secret); | |||||
| } | |||||
| /** | |||||
| * decode JWT | |||||
| * | |||||
| * @param string $token | |||||
| * @return array | |||||
| */ | |||||
| public function decode($token) | |||||
| { | |||||
| return JWT::decode($token, $this->secret, array('HS256')); | |||||
| } | |||||
| } | |||||
| @ -0,0 +1,16 @@ | |||||
| <?php | |||||
| namespace Gear\Auth\Middleware; | |||||
| /** | |||||
| * | |||||
| * | |||||
| * @author Björn Hase | |||||
| * @license http://opensource.org/licenses/MIT The MIT License | |||||
| * @link https://gitlab.tentakelfabrik.de/gear/gear-jwt | |||||
| */ | |||||
| interface AuthInterface | |||||
| { | |||||
| public function check($token); | |||||
| public function getUser(); | |||||
| } | |||||
| @ -0,0 +1,75 @@ | |||||
| <?php | |||||
| namespace Gear\Auth\Middleware; | |||||
| use Gear/FlightAbstract; | |||||
| /** | |||||
| * Abstract AuthMiddleware for Flight | |||||
| * | |||||
| * @author Björn Hase | |||||
| * @license http://opensource.org/licenses/MIT The MIT License | |||||
| * @link https://gitlab.tentakelfabrik.de/gear/gear-jwt | |||||
| */ | |||||
| abstract class AuthMiddlewareAbstract extends FlightAbstract implements AuthInterface | |||||
| { | |||||
| /** routes that are allowed and have not to authenficate */ | |||||
| protected $allowed = []; | |||||
| /** result of attempt */ | |||||
| protected $result = false; | |||||
| /** | |||||
| * | |||||
| * | |||||
| * @param array $allowed | |||||
| */ | |||||
| public function __construct($allowed) | |||||
| { | |||||
| parent::__construct(); | |||||
| $this->allowed = $allowed; | |||||
| } | |||||
| /** | |||||
| * attempt | |||||
| * | |||||
| * | |||||
| * @return mixed | |||||
| */ | |||||
| public function attempt() | |||||
| { | |||||
| $match = NULL; | |||||
| // search for pattern if route | |||||
| foreach($this->app->router()->getRoutes() as $route) { | |||||
| if ($route->matchUrl($this->app->request()->url)) { | |||||
| $match = $route; | |||||
| break; | |||||
| } | |||||
| } | |||||
| // if pattern is not in the allowed, get HTTP_AUTHORIZATION and parse bearer-token | |||||
| if (!in_array($match->pattern, $this->routes)) { | |||||
| if (isset($_SERVER['HTTP_AUTHORIZATION']) || isset($_SERVER['REDIRECT_HTTP_AUTHORIZATION'])) { | |||||
| if (isset($_SERVER['HTTP_AUTHORIZATION'])) { | |||||
| $header = $_SERVER['HTTP_AUTHORIZATION']; | |||||
| } | |||||
| if (isset($_SERVER['REDIRECT_HTTP_AUTHORIZATION'])) { | |||||
| $header = $_SERVER['REDIRECT_HTTP_AUTHORIZATION']; | |||||
| } | |||||
| $token = trim(preg_replace('/^(?:\s+)?Bearer\s/', '', $header)); | |||||
| $this->check($token); | |||||
| } | |||||
| } | |||||
| // if route not found, set $result to true | |||||
| if (!$match) { | |||||
| $this->result = true; | |||||
| } | |||||
| return $this->result; | |||||
| } | |||||
| } | |||||