350 lines
13 KiB
PHP

<?php
namespace Aiko;
use Aiko\Log;
use Firebase\JWT\JWT;
class Token
{
public function get_token($area = 'default')
{
$token = hash('sha512', mt_rand(0, mt_getrandmax()) . microtime(true));
$_SESSION['token'] = $token;
return $token;
}
public function check_token($token, $area = 'default')
{
// var_dump($_SESSION);
$sessiontoken = $this->get_token_from_session('token');
// var_dump($sessiontoken);
// exit();
$valid = strlen($sessiontoken) == 128 && strlen($token) == 128 && $sessiontoken == $token;
$this->get_token($area); // refresh token
return $valid;
}
public function get_token_from_url()
{
$token = isset($_GET['token']) ? $_GET['token'] : '';
return $token;
}
public function get_token_from_session($key)
{
$token = isset($_SESSION[$key]) ? $_SESSION[$key] : '';
return $token;
}
public function getTokenAuthUser()
{
$token = hash('sha512', mt_rand(0, mt_getrandmax()) . microtime(true));
$_SESSION['tokenAuth'] = $token;
return $token;
}
public function check_tokenAuthUser($token)
{
$sessiontoken = $this->get_token_from_session('tokenAuth');
$valid = strlen($sessiontoken) == 128 && strlen($token) == 128 && $sessiontoken == $token;
if ($valid) {
return true;
} else {
return false;
}
}
public function set_cookie()
{
$result = password_hash('4pl1k4s1D1sd1K', PASSWORD_DEFAULT, array('cost' => 10));
// $res = setcookie('XSRF-TOKEN', $result, time() + 86400, $_SERVER['REQUEST_URI'],'',false,false);
$res = setcookie('XSRF-TOKEN', $result, time() + 86400, '/');
if ($res) {
return true;
} else {
return false;
}
}
public function cek_cookie($clientCookie)
{
$result = false;
if (isset($_COOKIE['XSRF-TOKEN'])) {
$serverCookie = $_COOKIE['XSRF-TOKEN'];
$result = $this->cek_hash($clientCookie, $serverCookie);
}
return $result;
}
private function cek_hash($clientCookie, $serverCookie)
{
if ($clientCookie == $serverCookie) {
return $this->set_cookie();
} else {
return false;
}
}
private static function wrapToken($jwt, $chipper)
{
try {
if (strlen($chipper) <> 6) {
throw new \ErrorException('chipper failed');
}
$headerPreffix = (int) substr($chipper, 0, 1);
$headerSuffix = (int) substr($chipper, 1, 1);
$payloadPreffix = (int) substr($chipper, 2, 1);
$payloadSuffix = (int) substr($chipper, 3, 1);
$signPreffix = (int) substr($chipper, 4, 1);
$signSuffix = (int) substr($chipper, 5, 1);
$jwtPart = explode('.', $jwt);
$newJwt = self::randomChars($headerPreffix) . $jwtPart[0] . self::randomChars($headerSuffix);
$newJwt .= '.' . self::randomChars($payloadPreffix) . $jwtPart[1] . self::randomChars($payloadSuffix);
$newJwt .= '.' . self::randomChars($signPreffix) . $jwtPart[2] . self::randomChars($signSuffix);
return $newJwt;
} catch (\Exception $e) {
return false;
}
}
private static function unWrapToken($jwt, $chipper)
{
try {
if (strlen($chipper) <> 6) {
throw new \ErrorException('chipper failed');
}
$headerPreffix = (int) substr($chipper, 0, 1);
$headerSuffix = (int) substr($chipper, 1, 1);
$payloadPreffix = (int) substr($chipper, 2, 1);
$payloadSuffix = (int) substr($chipper, 3, 1);
$signPreffix = (int) substr($chipper, 4, 1);
$signSuffix = (int) substr($chipper, 5, 1);
$jwtPart = explode('.', $jwt);
$newString = self::removePreSuf($jwtPart[0], $headerPreffix, $headerSuffix);
if ($newString == false) {
throw new \ErrorException('failed clean wrapper header');
}
$header = $newString;
$newString = self::removePreSuf($jwtPart[1], $payloadPreffix, $payloadSuffix);
if ($newString == false) {
throw new \ErrorException('failed clean wrapper payload');
}
$payload = $newString;
$newString = self::removePreSuf($jwtPart[2], $signPreffix, $signSuffix);
if ($newString == false) {
throw new \ErrorException('failed clean wrapper sign');
}
$sign = $newString;
return $header . '.' . $payload . '.' . $sign;
} catch (\ErrorException $e) {
return false;
}
}
private static function removePreSuf($string, $preffix, $suffix)
{
$jum = strlen(trim($string));
$totWrapper = ($preffix + $suffix);
$tot = $totWrapper + 10; // set minimum text
if ($jum > $tot) {
$total = $jum - $totWrapper;
$newString = substr($string, $preffix, $total);
return $newString;
}
return false;
}
private static function randomChars($numChars)
{
$str = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuzwxyz';
return substr(str_shuffle($str), 0, $numChars);
}
public static function encodeJWT($serverName, $dataUser, $chipper = '000000')
{
try {
$log = new Log('1');
// $publicKey = file_get_contents('/Users/suhendra/mykey/suhendra_rsa.pub');
$privateKey = file_get_contents(__SITE_PATH . '/mykey/hcportalprivate.pem');
// $privateKey = openssl_get_privatekey('file:///Users/suhendra/mykey/suhendra_rsa','suh3ndr4');
// var_dump($privateKey);
//$tokenId = base64_encode(\mcrypt_create_iv(32));
$tokenId = base64_encode(\openssl_random_pseudo_bytes(64));
// $random = mt_rand(0, 999999);
// $random_string = sha1($random);
//$tokenId = base64_encode(date('Y-m-d H:i:s'));
$issuedAt = time();
$notBefore = time();
$expire = $notBefore + __LIFETIMEJWT; // Adding 10 menit
/*
* Create the token as an array
*/
$data = [
'iat' => $issuedAt, // Issued at: time when the token was generated
'jti' => $tokenId, // Json Token Id: an unique identifier for the token / A unique string, could be used to validate a token, but goes against not having a centralized issuer authority.
'iss' => $serverName, // A string containing the name or identifier of the issuer application. Can be a domain name and can be used to discard tokens from other applications.
'nbf' => $notBefore, // Timestamp of when the token should start being considered valid. Should be equal to or greater than iat. In this case, the token will begin to be valid 10 seconds
'exp' => $expire, // Timestamp of when the token should cease to be valid. Should be greater than iat and nbf. In this case, the token will expire 60 seconds after being issued.
'data' => $dataUser,
];
$jwt = JWT::encode(
$data, //Data to be encoded in the JWT
$privateKey, // The signing key
'RS256' // Algorithm used to sign the token, see https://tools.ietf.org/html/draft-ietf-jose-json-web-algorithms-40#section-3
);
// var_dump($jwt);
$newJwt = self::wrapToken($jwt, $chipper);
// var_dump($newJwt);
if ($newJwt == false) {
throw new \ErrorException('Failed wrap Token');
}
$dataUser['expired'] = $expire;
$dataHeader = array(
'jwt' => $newJwt,
'tokenID' => $tokenId,
'appID' => $serverName,
'data' => $dataUser,
'expired' => $expire
);
return $dataHeader;
} catch (\ErrorException $e) {
$log->error('encode token token/decodeJWT' . $e->getMessage());
return false;
}
}
public static function decodeJWT($jwt, $chipper = '000000')
{
try {
$log = new Log('1');
$publicKey = file_get_contents(__SITE_PATH . '/mykey/hcportalpublic.pem');
$newJwt = self::unWrapToken($jwt, $chipper);
$token = JWT::decode($newJwt, $publicKey, array('RS256'));
return $token;
} catch (\DomainException $e) {
$log->error('decode token token/decodeJWT' . $e->getMessage() . 'JWT |' . $jwt);
return false;
} catch (\InvalidArgumentException $e) {
$log->error('decode token token/decodeJWT' . $e->getMessage() . 'JWT |' . $jwt);
return false;
} catch (\UnexpectedValueException $e) {
$log->error('decode token token/decodeJWT' . $e->getMessage() . 'JWT |' . $jwt);
return false;
} catch (\DateTime $e) {
$log->error('decode token token/decodeJWT' . $e->getMessage() . 'JWT |' . $jwt);
return false;
} catch (\SignatureInvalidException $e) {
$log->error('decode token token/decodeJWT' . $e->getMessage() . 'JWT |' . $jwt);
return false;
} catch (\BeforeValidException $e) {
$log->error('decode token token/decodeJWT' . $e->getMessage() . 'JWT |' . $jwt);
return false;
} catch (\Firebase\JWT\ExpiredException $e) {
$log->error('decode token token/decodeJWT' . $e->getMessage() . 'JWT |' . $jwt);
return false;
}
}
public static function decodeJWTNew($jwt, $chipper = '000000')
{
try {
$log = new Log('1');
$publicKey = file_get_contents(__SITE_PATH . '/mykey/hcportalpublic.pem');
$newJwt = self::unWrapToken($jwt, $chipper);
$token = JWT::decode($newJwt, $publicKey, array('RS256'));
return $token;
} catch (\DomainException $e) {
$log->error('decode token token/decodeJWT 2 ' . $e->getMessage() . 'JWT |' . $jwt);
return 2;
} catch (\InvalidArgumentException $e) {
$log->error('decode token token/decodeJWT 3' . $e->getMessage() . 'JWT |' . $jwt);
return 3;
} catch (\UnexpectedValueException $e) {
$log->error('decode token token/decodeJWT 4' . $e->getMessage() . 'JWT |' . $jwt);
if ($e->getMessage() == 'Expired token') {
return 8;
}
return 4;
} catch (\DateTime $e) {
$log->error('decode token token/decodeJWT 5' . $e->getMessage() . 'JWT |' . $jwt);
return 5;
} catch (\SignatureInvalidException $e) {
$log->error('decode token token/decodeJWT 6' . $e->getMessage() . 'JWT |' . $jwt);
return 6;
} catch (\BeforeValidException $e) {
$log->error('decode token token/decodeJWT 7' . $e->getMessage() . 'JWT |' . $jwt);
return 7;
} catch (\Firebase\JWT\ExpiredException $e) {
$log->error('decode token token/decodeJWT 8' . $e->getMessage() . 'JWT |' . $jwt);
return 8;
}
}
public static function decodePlainJWT($jwt, $key = null)
{
try {
$log = new Log('1');
$token = JWT::decode($jwt, $key, array('HS256'));
return $token;
} catch (\DomainException $e) {
$log->error('decode token token/decodeJWT' . $e->getMessage() . 'JWT |' . $jwt);
return false;
} catch (\InvalidArgumentException $e) {
$log->error('decode token token/decodeJWT' . $e->getMessage() . 'JWT |' . $jwt);
return false;
} catch (\UnexpectedValueException $e) {
$log->error('decode token token/decodeJWT' . $e->getMessage() . 'JWT |' . $jwt);
return false;
} catch (\Firebase\JWT\SignatureInvalidException $e) {
$log->error('decode token token/decodeJWT' . $e->getMessage() . 'JWT |' . $jwt);
return false;
} catch (\Firebase\JWT\BeforeValidException $e) {
$log->error('decode token token/decodeJWT' . $e->getMessage() . 'JWT |' . $jwt);
return false;
} catch (\Firebase\JWT\ExpiredException $e) {
$log->error('decode token token/decodeJWT' . $e->getMessage() . 'JWT |' . $jwt);
return false;
}
}
}