Skip to content

Commit

Permalink
Merge pull request #11 from byjg/2.0.0
Browse files Browse the repository at this point in the history
Release 2.0.0
  • Loading branch information
byjg authored Jan 9, 2019
2 parents cadf6d7 + 6d01a12 commit 6f31d19
Show file tree
Hide file tree
Showing 11 changed files with 361 additions and 64 deletions.
107 changes: 91 additions & 16 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,10 @@ Before the session_start() use the command:

```php
<?php
$handler = new \ByJG\Session\JwtSession('your.domain.com', 'your super secret key');
$sessionConfig = (new \ByJG\Session\SessionConfig('your.domain.com'))
->withSecret('your super secret key');

$handler = new \ByJG\Session\JwtSession($sessionConfig);
session_set_save_handler($handler, true);
```

Expand All @@ -34,7 +37,7 @@ Just to use.
You can read more in this Codementor's article:
[Using JSON Web Token (JWT) as a PHP Session](https://www.codementor.io/byjg/using-json-web-token-jwt-as-a-php-session-axeuqbg1m)

## Security Information
# Security Information

The JWT Token cannot be changed, but it can be read.
This implementation save the JWT into a client cookie.
Expand All @@ -43,47 +46,119 @@ Because of this _**do not** store in the JWT Token sensible data like passwords_
# Install

```
composer require "byjg/jwt-session=1.0.*"
composer require "byjg/jwt-session=2.0.*"
```

# Customizations

## Setting the validity of JWT Token
# Setting the validity of JWT Token

```php
<?php
// Setting to 50 minutes
$handler = new \ByJG\Session\JwtSession('your.domain.com', 'your super secret key', 50);
$sessionConfig = (new \ByJG\Session\SessionConfig('your.domain.com'))
->withSecret('your super secret key')
->withTimeoutMinutes(60); // You can use withTimeoutHours(1)

$handler = new \ByJG\Session\JwtSession($sessionConfig);
session_set_save_handler($handler, true);
```

## Setting the different Session Contexts
# Setting the different Session Contexts

```php
<?php
$handler = new \ByJG\Session\JwtSession('your.domain.com', 'your super secret key', 20, 'MYCONTEXT');
$sessionConfig = (new \ByJG\Session\SessionConfig('your.domain.com'))
->withSecret('your super secret key')
->withSessionContext('MYCONTEXT');

$handler = new \ByJG\Session\JwtSession($sessionConfig);
session_set_save_handler($handler, true);
```

## Create the handler and replace the session handler
# Create the handler and replace the session handler

```php
<?php
$sessionConfig = (new \ByJG\Session\SessionConfig('your.domain.com'))
->withSecret('your super secret key')
->replaceSessionHandler();

$handler = new \ByJG\Session\JwtSession($sessionConfig);
```

# Specify cookie domain

```php
<?php
$handler = new \ByJG\Session\JwtSession('your.domain.com', 'your super secret key');
$handler->replaceSessionHandler(true);
$sessionConfig = (new \ByJG\Session\SessionConfig('your.domain.com'))
->withSecret('your super secret key')
->withCookie('.mydomain.com', '/')
->replaceSessionHandler();

$handler = new \ByJG\Session\JwtSession($sessionConfig);
```

## Create the handler and replace the session handler, specifying cookie domain valid for all subdomains of mydomain.com
# Uses RSA Private/Public Keys

```php
<?php
$handler = new \ByJG\Session\JwtSession('your.domain.com', 'your super secret key', null, null, '.mydomain.com');
$handler->replaceSessionHandler(true);
$secret = <<<PRIVATE
-----BEGIN RSA PRIVATE KEY-----
MIIEpQIBAAKCAQEA5PMdWRa+rUJmg6QMNAPIXa+BJVN7W0vxPN3WTK/OIv5gxgmj
2inHGGc6f90TW/to948LnqGtcD3CD9KsI55MubafwBYjcds1o9opZ0vYwwdIV80c
OVZX1IUZFTbnyyKcXeFmKt49A52haCiy4iNxcRK38tOCApjZySx/NzMDeaXuWe+1
nd3pbgYa/I8MkECa5EyabhZJPJo9fGoSZIklNnyq4TfAUSwl+KN/zjj3CXad1oDT
7XDDgMJDUu/Vxs7h3CQI9zILSYcL9zwttbLnJW1WcLlAAIaAfABtSZboznsStMnY
to01wVknXKyERFs7FLHYqKQANIvRhFTptsehowIDAQABAoIBAEkJkaQ5EE0fcKqw
K8BwMHxKn81zi1e9q1C6iEHgl8csFV03+BCB4WTUkaH2udVPJ9ZJyPArLbQvz3fS
wl1+g4V/UAksRtRslPkXgLvWQ2k8KoTwBv/3nn9Kkozk/h8chHuii0BDs30yzSn4
SdDAc9EZopsRhFklv9xgmJjYalRk02OLck73G+d6MpDqX56o2UA/lf6i9MV19KWP
HYip7CAN+i6k8gA0KPHwr76ehgQ6YHtSntkWS8RfVI8fLUB1UlT3HmLgUBNXMWkQ
ZZbvXtNOt6NtW/WIAHEYeE9jmFgrpW5jKJSLn5iGVPFZwJIZXRPyELEs9NHWkS6e
GmdzxnECgYEA8+m05B/tmeZOuMrPVJV9g+aBDcuxmW+sdLRch+ccSmx4ZNQOLVoU
klYgTZq/a1O4ENq0h2WgccNlRHdcH4sXMBvLalA/tFhZMUuA/KXWyZ1F0hBnjHVF
cj1alHCqh+9qJDGdn4mxSmrp8p0rfeWgBwlFtJEJmjjDWDCtVY+JZcsCgYEA8EuV
WF/ilgDjgC4jMCYNuO0oFGBbtNP17PuU3kh8W+joqK/nufZ3NLy1WrDIpqa9YPex
328Nnjljf5GJWSdMchAp82waLzl7FaaBTY0iyFAK4J0jfC/fVLx82+wpM3utDnh8
9x5iIboO5U7uEJ7k8X2p64GoprlKJSRmGAJ7eIkCgYEAw5IsXI3NMY0cqcbUHvoO
PehgqfMdX+3O1XSYjM+eO35lulLdWzfTLtKn7BGcUi46dCkofzfZQd5uIEukLhaU
bRqcK45UxgHg4kmsDufaJKZaCWjl3hVZrZPMQSFlWsF41bSCshzxbr3y/3lOGhA4
E+w3W+S/Uk0ZNGkzUltYy6kCgYEA0gRNeBr9z7rhG4O3j3qC3dCxCfYZ0Na8hy5v
M0PJJQ9QYTa04iyOjVItcyE1jaoHtLtoA+9syJBB7RoHIBufzcVg1Pbzf7jOYeLP
+jbTYp3Kk/vjKsQwfj/rJM+oRu3eF9qo5dbxT6btI++zVGV7lbEOFN6Sx30EV6gT
bwKkZXkCgYEAnEtN43xL8bRFybMc1ZJErjc0VocnoQxCHm7LuAtLOEUw6CwwFj9Q
GOl+GViVuDHUNQvURLn+6gg4tAemYlob912xIPaU44+lZzTMHBOJBGMJKi8WogKi
V5+cz9l31uuAgNfjL63jZPaAzKs8Zx6R3O5RuezympwijCIGWILbO2Q=
-----END RSA PRIVATE KEY-----
PRIVATE;

$public = <<<PUBLIC
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA5PMdWRa+rUJmg6QMNAPI
Xa+BJVN7W0vxPN3WTK/OIv5gxgmj2inHGGc6f90TW/to948LnqGtcD3CD9KsI55M
ubafwBYjcds1o9opZ0vYwwdIV80cOVZX1IUZFTbnyyKcXeFmKt49A52haCiy4iNx
cRK38tOCApjZySx/NzMDeaXuWe+1nd3pbgYa/I8MkECa5EyabhZJPJo9fGoSZIkl
Nnyq4TfAUSwl+KN/zjj3CXad1oDT7XDDgMJDUu/Vxs7h3CQI9zILSYcL9zwttbLn
JW1WcLlAAIaAfABtSZboznsStMnYto01wVknXKyERFs7FLHYqKQANIvRhFTptseh
owIDAQAB
-----END PUBLIC KEY-----
PUBLIC;

$sessionConfig = (new \ByJG\Session\SessionConfig('example.com'))
->withRsaSecret($secret, $public)
->replaceSessionHandler();

$handler = new \ByJG\Session\JwtSession($sessionConfig);
```

## How it works
If you want to know more details about how to create RSA Public/Private Keys access:
https://github.com/byjg/jwt-wrapper


# How it works

We store a cookie named AUTH_BEARER_<context name> with the session name. The PHPSESSID cookie is still created because
PHP create it by default but we do not use it;


----
[Open source ByJG](http://opensource.byjg.com)
17 changes: 15 additions & 2 deletions _config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -41,13 +41,26 @@ social:
hash: opensourcebyjg
account:
facebook:
enabled: false
enabled: true
url: https://opensource.byjg.com/
profileUrl:

author:
twitter: byjg

twitter:
card: summary
username: byjg

logo: https://opensource.byjg.com/images/logo_byjg.png

analytics:
google: UA-130014324-1

plugins:
- jekyll-seo-tag

# Build settings
markdown: kramdown
remote_theme: allejo/jekyll-docs-theme
remote_theme: byjg/jekyll-docs-theme

2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
"prefer-stable": true,
"require": {
"php": ">=5.6.0",
"byjg/jwt-wrapper": "1.0.*"
"byjg/jwt-wrapper": "2.0.*"
},
"require-dev": {
"phpunit/phpunit": ">=5.7"
Expand Down
85 changes: 49 additions & 36 deletions src/JwtSession.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,48 +9,45 @@ class JwtSession implements SessionHandlerInterface
{
const COOKIE_PREFIX = "AUTH_BEARER_";

protected $serverName;

protected $secretKey;

protected $timeOutMinutes;

protected $suffix = "default";

protected $cookieDomain;

protected $path = "/";
/**
* @var SessionConfig
*/
protected $sessionConfig;

/**
* JwtSession constructor.
*
* @param $serverName
* @param $secretKey
* @param int $timeOutMinutes
* @param $sessionConfig
* @throws JwtSessionException
*/
public function __construct($serverName, $secretKey, $timeOutMinutes = null, $sessionContext = null, $cookieDomain = null, $path = "/")
public function __construct($sessionConfig)
{
$this->serverName = $serverName;
$this->secretKey = $secretKey;
$this->timeOutMinutes = $timeOutMinutes ?: 20;
$this->suffix = $sessionContext ?: 'default';
$this->cookieDomain = $cookieDomain;
$this->path = "/";
ini_set("session.use_cookies", 0);

if (!($sessionConfig instanceof SessionConfig)) {
throw new JwtSessionException('Required SessionConfig instance');
}

$this->sessionConfig = $sessionConfig;

if ($this->sessionConfig->isReplaceSession()) {
$this->replaceSessionHandler();
}
}

/**
* @param bool $startSession
* @throws JwtSessionException
*/
public function replaceSessionHandler($startSession = true)
protected function replaceSessionHandler()
{
if (session_status() != PHP_SESSION_NONE) {
throw new JwtSessionException('Session already started!');
}

session_set_save_handler($this, true);

if ($startSession) {
if ($this->sessionConfig->isStartSession()) {
ob_start();
session_start();
}
Expand Down Expand Up @@ -86,11 +83,11 @@ public function destroy($session_id)
{
if (!headers_sent()) {
setcookie(
self::COOKIE_PREFIX . $this->suffix,
self::COOKIE_PREFIX . $this->sessionConfig->getSessionContext(),
null,
(time()-3000),
$this->path,
$this->cookieDomain
$this->sessionConfig->getCookiePath(),
$this->sessionConfig->getCookieDomain()
);
}

Expand Down Expand Up @@ -148,9 +145,16 @@ public function open($save_path, $name)
public function read($session_id)
{
try {
if (isset($_COOKIE[self::COOKIE_PREFIX . $this->suffix])) {
$jwt = new JwtWrapper($this->serverName, $this->secretKey);
$data = $jwt->extractData($_COOKIE[self::COOKIE_PREFIX . $this->suffix]);
if (isset($_COOKIE[self::COOKIE_PREFIX . $this->sessionConfig->getSessionContext()])) {
$jwt = new JwtWrapper(
$this->sessionConfig->getServerName(),
$this->sessionConfig->getKey()
);
$data = $jwt->extractData($_COOKIE[self::COOKIE_PREFIX . $this->sessionConfig->getSessionContext()]);

if (empty($data->data)) {
return '';
}

return $data->data;
}
Expand All @@ -176,26 +180,30 @@ public function read($session_id)
* The return value (usually TRUE on success, FALSE on failure).
* Note this value is returned internally to PHP for processing.
* </p>
* @throws \ByJG\Util\JwtWrapperException
* @since 5.4.0
*/
public function write($session_id, $session_data)
{
$jwt = new JwtWrapper($this->serverName, $this->secretKey);
$data = $jwt->createJwtData($session_data, $this->timeOutMinutes * 60);
$jwt = new JwtWrapper(
$this->sessionConfig->getServerName(),
$this->sessionConfig->getKey()
);
$data = $jwt->createJwtData($session_data, $this->sessionConfig->getTimeoutMinutes() * 60);
$token = $jwt->generateToken($data);

if (!headers_sent()) {
setcookie(
self::COOKIE_PREFIX . $this->suffix,
self::COOKIE_PREFIX . $this->sessionConfig->getSessionContext(),
$token,
(time()+$this->timeOutMinutes*60) ,
$this->path,
$this->cookieDomain,
(time()+$this->sessionConfig->getTimeoutMinutes()*60) ,
$this->sessionConfig->getCookiePath(),
$this->sessionConfig->getCookieDomain(),
false,
true
);
if (defined("SETCOOKIE_FORTEST")) {
$_COOKIE[self::COOKIE_PREFIX . $this->suffix] = $token;
$_COOKIE[self::COOKIE_PREFIX . $this->sessionConfig->getSessionContext()] = $token;
}
}

Expand All @@ -212,6 +220,11 @@ public function serializeSessionData($array)
return $result;
}

/**
* @param $session_data
* @return array
* @throws JwtSessionException
*/
public function unSerializeSessionData($session_data)
{
$return_data = array();
Expand Down
Loading

0 comments on commit 6f31d19

Please sign in to comment.