Skip to content

Commit e46c75d

Browse files
committed
Simples Security package
0 parents  commit e46c75d

File tree

5 files changed

+251
-0
lines changed

5 files changed

+251
-0
lines changed

LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2016 Grupo de PHP da Zona da Mata
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

composer.json

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
{
2+
"name": "phpzm/security",
3+
"description": "Simples Security package",
4+
"minimum-stability": "dev",
5+
"keywords": [
6+
"php",
7+
"framework",
8+
"api",
9+
"simples"
10+
],
11+
"homepage": "https://github.com/phpzm/security",
12+
"license": "MIT",
13+
"version": "1.0.0",
14+
"type": "package",
15+
"authors": [
16+
{
17+
"name": "William",
18+
"email": "wilcorrea@gmail.com"
19+
},
20+
{
21+
"name": "Ezio",
22+
"email": "ezioadsr@gmail.com"
23+
}
24+
],
25+
"require": {
26+
"php": ">=7.0",
27+
"phpzm/helper": "dev-master",
28+
"phpzm/http": "dev-master"
29+
},
30+
"autoload": {
31+
"psr-4": {
32+
"Simples\\Security\\": "src/"
33+
}
34+
}
35+
}

src/Auth.php

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
<?php
2+
3+
namespace Simples\Security;
4+
5+
use Simples\Http\Kernel\App;
6+
7+
/**
8+
* Class Auth
9+
* @package Simples\Security
10+
*/
11+
abstract class Auth
12+
{
13+
/**
14+
* @var string
15+
*/
16+
const PAYLOAD_USER = 'user', PAYLOAD_DEVICE = 'device';
17+
18+
/**
19+
* @param string $password
20+
* @return string
21+
*/
22+
public static function crypt(string $password): string
23+
{
24+
return password_hash($password, PASSWORD_DEFAULT);
25+
}
26+
27+
/**
28+
* @param string $password
29+
* @param string $candidate
30+
* @return bool
31+
*/
32+
public static function match(string $password, string $candidate): bool
33+
{
34+
return password_verify($password, $candidate);
35+
}
36+
37+
/**
38+
* @return string
39+
*/
40+
public static function getToken()
41+
{
42+
return App::request()->getHeader(env('AUTH_TOKEN'));
43+
}
44+
45+
/**
46+
* @param string $user
47+
* @param string $device
48+
* @param array $options
49+
* @return string
50+
*/
51+
public static function createToken(string $user, string $device, array $options = []): string
52+
{
53+
$data = [
54+
self::PAYLOAD_USER => $user,
55+
self::PAYLOAD_DEVICE => $device
56+
];
57+
return JWT::create(array_merge($options, $data), env('SECURITY'));
58+
}
59+
60+
/**
61+
* @param string $property
62+
* @return string
63+
*/
64+
public static function getTokenValue(string $property): string
65+
{
66+
$token = self::getToken();
67+
if (!$token) {
68+
return '';
69+
}
70+
return off(JWT::payload($token, env('SECURITY')), $property);
71+
}
72+
73+
/**
74+
* @return string
75+
*/
76+
public static function getUser(): string
77+
{
78+
return self::getTokenValue(self::PAYLOAD_USER);
79+
}
80+
81+
/**
82+
* @return string
83+
*/
84+
public static function getDevice(): string
85+
{
86+
return self::getTokenValue(self::PAYLOAD_DEVICE);
87+
}
88+
}

src/Encryption.php

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
<?php
2+
3+
namespace Simples\Security;
4+
5+
/**
6+
* Class Encryption
7+
* @package Simples\Security
8+
*/
9+
class Encryption
10+
{
11+
/**
12+
* @var string
13+
*/
14+
const ENCRYPT_MODE = "AES-256-CBC";
15+
16+
/**
17+
* @param string $string
18+
* @param string $secretKey
19+
* @return string
20+
*/
21+
public static function encode($string, $secretKey): string
22+
{
23+
$key = hash('sha256', $secretKey);
24+
$iv = substr(hash('sha256', md5($secretKey)), 0, 16);
25+
26+
return base64_encode(openssl_encrypt($string, self::ENCRYPT_MODE, $key, 0, $iv));
27+
}
28+
29+
/**
30+
* @param string $string
31+
* @param string $secretKey
32+
* @return string
33+
*/
34+
public static function decode(string $string, string $secretKey): string
35+
{
36+
$key = hash('sha256', $secretKey);
37+
$iv = substr(hash('sha256', md5($secretKey)), 0, 16);
38+
39+
return openssl_decrypt(base64_decode($string), self::ENCRYPT_MODE, $key, 0, $iv);
40+
}
41+
}

src/JWT.php

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
<?php
2+
3+
namespace Simples\Security;
4+
5+
use Simples\Helper\JSON;
6+
use Simples\Http\Error\SimplesForbiddenError;
7+
8+
/**
9+
* Class Jwt
10+
* @package Simples\Security
11+
*/
12+
abstract class JWT
13+
{
14+
/**
15+
* @param array $data
16+
* @param string $secret
17+
* @return string
18+
*/
19+
public static function create(array $data, string $secret): string
20+
{
21+
$header = base64_encode(json_encode(['type' => 'JWT', 'alg' => 'HS256']));
22+
23+
$payload = base64_encode(Encryption::encode(JSON::encode($data), $secret));
24+
25+
$signature = base64_encode(hash_hmac('sha256', "{$header}.{$payload}", $secret, true));
26+
27+
return "{$header}.{$payload}.{$signature}";
28+
}
29+
30+
/**
31+
* @param string $token
32+
* @param string $secret
33+
* @return array
34+
* @throws SimplesForbiddenError
35+
*/
36+
public static function payload(string $token, string $secret): array
37+
{
38+
if (!static::verify($token, $secret)) {
39+
throw new SimplesForbiddenError("The token '{$token}' is invalid");
40+
}
41+
$peaces = explode('.', $token);
42+
if (count($peaces) !== 3) {
43+
throw new SimplesForbiddenError("The token '{$token}' is invalid");
44+
}
45+
return (array)JSON::decode(Encryption::decode(base64_decode($peaces[1]), $secret));
46+
}
47+
48+
/**
49+
* @param string $token
50+
* @param string $secret
51+
* @return bool
52+
*/
53+
public static function verify(string $token, string $secret): bool
54+
{
55+
$peaces = explode('.', $token);
56+
if (count($peaces) < 3) {
57+
return false;
58+
}
59+
$header = $peaces[0];
60+
$payload = $peaces[1];
61+
$signature = $peaces[2];
62+
$hash = base64_encode(hash_hmac('sha256', "{$header}.{$payload}", $secret, true));
63+
64+
return hash_equals($signature, $hash);
65+
}
66+
}

0 commit comments

Comments
 (0)