Skip to content

Commit aac97fd

Browse files
authored
Merge pull request #20 from byjg/6.0
6.0
2 parents 30de803 + 6ea193f commit aac97fd

File tree

6 files changed

+60
-20
lines changed

6 files changed

+60
-20
lines changed

.github/workflows/phpunit.yml

Lines changed: 32 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,15 +18,44 @@ jobs:
1818
strategy:
1919
matrix:
2020
php-version:
21+
- "8.5"
2122
- "8.4"
2223
- "8.3"
23-
- "8.2"
24-
- "8.1"
2524

2625
steps:
2726
- uses: actions/checkout@v5
2827
- run: composer install
29-
- run: ./vendor/bin/phpunit
28+
- run: composer test
29+
30+
Psalm:
31+
name: Psalm Static Analyzer
32+
runs-on: ubuntu-latest
33+
permissions:
34+
# for github/codeql-action/upload-sarif to upload SARIF results
35+
security-events: write
36+
container:
37+
image: byjg/php:8.4-cli
38+
options: --user root --privileged
39+
40+
steps:
41+
- name: Git checkout
42+
uses: actions/checkout@v4
43+
44+
- name: Composer
45+
run: composer install
46+
47+
- name: Psalm
48+
# Note: Ignoring error code 2, which just signals that some
49+
# flaws were found, not that Psalm itself failed to run.
50+
run: ./vendor/bin/psalm
51+
--show-info=true
52+
--report=psalm-results.sarif || [ $? = 2 ]
53+
54+
- name: Upload Analysis results to GitHub
55+
uses: github/codeql-action/upload-sarif@v4
56+
if: github.ref == 'refs/heads/master'
57+
with:
58+
sarif_file: psalm-results.sarif
3059

3160
Documentation:
3261
if: github.ref == 'refs/heads/master'

README.md

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
1-
# JwtSession
1+
# JWT Session Handler
22

3-
[![Build Status](https://github.com/byjg/jwt-session/actions/workflows/phpunit.yml/badge.svg?branch=master)](https://github.com/byjg/jwt-session/actions/workflows/phpunit.yml)
4-
[![Opensource ByJG](https://img.shields.io/badge/opensource-byjg-success.svg)](http://opensource.byjg.com)
5-
[![GitHub source](https://img.shields.io/badge/Github-source-informational?logo=github)](https://github.com/byjg/jwt-session/)
6-
[![GitHub license](https://img.shields.io/github/license/byjg/jwt-session.svg)](https://opensource.byjg.com/opensource/licensing.html)
3+
[![Sponsor](https://img.shields.io/badge/Sponsor-%23ea4aaa?logo=githubsponsors&logoColor=white&labelColor=0d1117)](https://github.com/sponsors/byjg)
4+
[![Build Status](https://github.com/byjg/jwt-session/actions/workflows/phpunit.yml/badge.svg?branch=master)](https://github.com/byjg/jwt-session/actions/workflows/phpunit.yml)
5+
[![Opensource ByJG](https://img.shields.io/badge/opensource-byjg-success.svg)](http://opensource.byjg.com)
6+
[![GitHub source](https://img.shields.io/badge/Github-source-informational?logo=github)](https://github.com/byjg/jwt-session/)
7+
[![GitHub license](https://img.shields.io/github/license/byjg/jwt-session.svg)](https://opensource.byjg.com/opensource/licensing.html)
78
[![GitHub release](https://img.shields.io/github/release/byjg/jwt-session.svg)](https://github.com/byjg/jwt-session/releases/)
89

9-
JwtSession is a PHP session replacement. Instead of use FileSystem, just use JWT TOKEN.
10-
The implementation following the SessionHandlerInterface.
10+
A PHP session replacement that stores session data in JWT tokens instead of the filesystem. This implementation follows the SessionHandlerInterface standard, enabling stateless sessions without the need for dedicated session servers like Redis or Memcached. Perfect for distributed applications and microservices architectures.
1111

1212
# How to use:
1313

composer.json

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "byjg/jwt-session",
3-
"description": "JwtSession is a PHP session replacement. Instead of use FileSystem, just use JWT TOKEN. The implementation following the SessionHandlerInterface.",
3+
"description": "A PHP session replacement that stores session data in JWT tokens instead of the filesystem. This implementation follows the SessionHandlerInterface standard, enabling stateless sessions without the need for dedicated session servers like Redis or Memcached. Perfect for distributed applications and microservices architectures.",
44
"autoload": {
55
"psr-4": {
66
"ByJG\\Session\\": "src/"
@@ -9,16 +9,16 @@
99
"minimum-stability": "dev",
1010
"prefer-stable": true,
1111
"require": {
12-
"php": ">=8.1 <8.5",
12+
"php": ">=8.3 <8.6",
1313
"byjg/jwt-wrapper": "^6.0"
1414
},
1515
"require-dev": {
16-
"phpunit/phpunit": "^10|^11",
17-
"vimeo/psalm": "^5.9|^6.12"
16+
"phpunit/phpunit": "^10.5|^11.5",
17+
"vimeo/psalm": "^5.9|^6.13"
1818
},
1919
"scripts": {
2020
"test": "vendor/bin/phpunit",
21-
"psalm": "vendor/bin/psalm"
21+
"psalm": "vendor/bin/psalm --threads=1"
2222
},
2323
"license": "MIT"
2424
}

psalm.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<?xml version="1.0"?>
22
<psalm
3-
errorLevel="4"
3+
errorLevel="3"
44
resolveFromConfigFile="true"
55
findUnusedBaselineEntry="true"
66
findUnusedCode="false"

src/JwtSession.php

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99

1010
class JwtSession implements SessionHandlerInterface
1111
{
12-
const COOKIE_PREFIX = "AUTH_BEARER_";
12+
const string COOKIE_PREFIX = "AUTH_BEARER_";
1313

1414
/**
1515
* @var SessionConfig
@@ -152,9 +152,13 @@ public function read(string $id): string
152152
{
153153
try {
154154
if (isset($_COOKIE[self::COOKIE_PREFIX . $this->sessionConfig->getSessionContext()])) {
155+
$key = $this->sessionConfig->getKey();
156+
if ($key === null) {
157+
return '';
158+
}
155159
$jwt = new JwtWrapper(
156160
$this->sessionConfig->getServerName(),
157-
$this->sessionConfig->getKey()
161+
$key
158162
);
159163
$data = $jwt->extractData($_COOKIE[self::COOKIE_PREFIX . $this->sessionConfig->getSessionContext()]);
160164

@@ -192,9 +196,13 @@ public function read(string $id): string
192196
#[\Override]
193197
public function write(string $id, string $data): bool
194198
{
199+
$key = $this->sessionConfig->getKey();
200+
if ($key === null) {
201+
return false;
202+
}
195203
$jwt = new JwtWrapper(
196204
$this->sessionConfig->getServerName(),
197-
$this->sessionConfig->getKey()
205+
$key
198206
);
199207
$session_data = $jwt->createJwtData(['data' => $data], $this->sessionConfig->getTimeoutMinutes() * 60, 0, null);
200208
$token = $jwt->generateToken($session_data);
@@ -239,6 +247,9 @@ public function unSerializeSessionData($session_data): array
239247
while ($offset < strlen($session_data)) {
240248
if (!str_contains(substr($session_data, $offset), "|")) throw new JwtSessionException("invalid data, remaining: " . substr($session_data, $offset));
241249
$pos = strpos($session_data, "|", $offset);
250+
if ($pos === false) {
251+
throw new JwtSessionException("invalid data, pipe not found");
252+
}
242253
$num = $pos - $offset;
243254
$varname = substr($session_data, $offset, $num);
244255
$offset += $num + 1;

tests/JwtSessionTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ class JwtSessionTest extends TestCase
2222
*/
2323
protected SessionConfig $sessionConfig;
2424

25-
const SESSION_ID = "sessionid";
25+
const string SESSION_ID = "sessionid";
2626

2727
/**
2828
* @throws JwtSessionException

0 commit comments

Comments
 (0)