1
+ <?php
2
+ /**
3
+ * User: jg
4
+ * Date: 14/02/17
5
+ * Time: 12:52
6
+ */
7
+
8
+ namespace ByJG \Session ;
9
+
10
+ use ByJG \Util \JwtWrapper ;
11
+ use SessionHandlerInterface ;
12
+
13
+ class JwtSession implements SessionHandlerInterface
14
+ {
15
+ const COOKIE_PREFIX = "AUTH_BEARER_ " ;
16
+
17
+ protected $ serverName ;
18
+
19
+ protected $ secretKey ;
20
+
21
+ protected $ timeOutMinutes ;
22
+
23
+ protected $ suffix = "default " ;
24
+
25
+ /**
26
+ * JwtSession constructor.
27
+ *
28
+ * @param $serverName
29
+ * @param $secretKey
30
+ * @param int $timeOutMinutes
31
+ */
32
+ public function __construct ($ serverName , $ secretKey , $ timeOutMinutes = 20 , $ sessionContext = 'default ' )
33
+ {
34
+ $ this ->serverName = $ serverName ;
35
+ $ this ->secretKey = $ secretKey ;
36
+ $ this ->timeOutMinutes = $ timeOutMinutes ;
37
+ $ this ->suffix = $ sessionContext ;
38
+ }
39
+
40
+ public function replaceSessionHandler ($ startSession = true )
41
+ {
42
+ if (session_status () != PHP_SESSION_NONE ) {
43
+ throw new \Exception ('Session already started! ' );
44
+ }
45
+
46
+ session_set_save_handler ($ this , true );
47
+
48
+ if ($ startSession ) {
49
+ ob_start ();
50
+ session_start ();
51
+ }
52
+ }
53
+
54
+ /**
55
+ * Close the session
56
+ *
57
+ * @link http://php.net/manual/en/sessionhandlerinterface.close.php
58
+ * @return bool <p>
59
+ * The return value (usually TRUE on success, FALSE on failure).
60
+ * Note this value is returned internally to PHP for processing.
61
+ * </p>
62
+ * @since 5.4.0
63
+ */
64
+ public function close ()
65
+ {
66
+ return true ;
67
+ }
68
+
69
+ /**
70
+ * Destroy a session
71
+ *
72
+ * @link http://php.net/manual/en/sessionhandlerinterface.destroy.php
73
+ * @param string $session_id The session ID being destroyed.
74
+ * @return bool <p>
75
+ * The return value (usually TRUE on success, FALSE on failure).
76
+ * Note this value is returned internally to PHP for processing.
77
+ * </p>
78
+ * @since 5.4.0
79
+ */
80
+ public function destroy ($ session_id )
81
+ {
82
+ setcookie (self ::COOKIE_PREFIX . $ this ->suffix , null );
83
+ return true ;
84
+ }
85
+
86
+ /**
87
+ * Cleanup old sessions
88
+ *
89
+ * @link http://php.net/manual/en/sessionhandlerinterface.gc.php
90
+ * @param int $maxlifetime <p>
91
+ * Sessions that have not updated for
92
+ * the last maxlifetime seconds will be removed.
93
+ * </p>
94
+ * @return bool <p>
95
+ * The return value (usually TRUE on success, FALSE on failure).
96
+ * Note this value is returned internally to PHP for processing.
97
+ * </p>
98
+ * @since 5.4.0
99
+ */
100
+ public function gc ($ maxlifetime )
101
+ {
102
+ return true ;
103
+ }
104
+
105
+ /**
106
+ * Initialize session
107
+ *
108
+ * @link http://php.net/manual/en/sessionhandlerinterface.open.php
109
+ * @param string $save_path The path where to store/retrieve the session.
110
+ * @param string $name The session name.
111
+ * @return bool <p>
112
+ * The return value (usually TRUE on success, FALSE on failure).
113
+ * Note this value is returned internally to PHP for processing.
114
+ * </p>
115
+ * @since 5.4.0
116
+ */
117
+ public function open ($ save_path , $ name )
118
+ {
119
+ return true ;
120
+ }
121
+
122
+ /**
123
+ * Read session data
124
+ *
125
+ * @link http://php.net/manual/en/sessionhandlerinterface.read.php
126
+ * @param string $session_id The session id to read data for.
127
+ * @return string <p>
128
+ * Returns an encoded string of the read data.
129
+ * If nothing was read, it must return an empty string.
130
+ * Note this value is returned internally to PHP for processing.
131
+ * </p>
132
+ * @since 5.4.0
133
+ */
134
+ public function read ($ session_id )
135
+ {
136
+ try {
137
+ if (isset ($ _COOKIE [self ::COOKIE_PREFIX . $ this ->suffix ])) {
138
+ $ jwt = new JwtWrapper ($ this ->serverName , $ this ->secretKey );
139
+ $ data = $ jwt ->extractData ($ _COOKIE [self ::COOKIE_PREFIX . $ this ->suffix ]);
140
+
141
+ return $ this ->serializeSessionData ($ data ->data );
142
+ }
143
+ return '' ;
144
+ } catch (\Exception $ ex ) {
145
+ return '' ;
146
+ }
147
+ }
148
+
149
+ /**
150
+ * Write session data
151
+ *
152
+ * @link http://php.net/manual/en/sessionhandlerinterface.write.php
153
+ * @param string $session_id The session id.
154
+ * @param string $session_data <p>
155
+ * The encoded session data. This data is the
156
+ * result of the PHP internally encoding
157
+ * the $_SESSION superglobal to a serialized
158
+ * string and passing it as this parameter.
159
+ * Please note sessions use an alternative serialization method.
160
+ * </p>
161
+ * @return bool <p>
162
+ * The return value (usually TRUE on success, FALSE on failure).
163
+ * Note this value is returned internally to PHP for processing.
164
+ * </p>
165
+ * @since 5.4.0
166
+ */
167
+ public function write ($ session_id , $ session_data )
168
+ {
169
+ $ jwt = new JwtWrapper ($ this ->serverName , $ this ->secretKey );
170
+ $ data = $ jwt ->createJwtData ($ this ->unSerializeSessionData ($ session_data ), $ this ->timeOutMinutes * 60 );
171
+ $ token = $ jwt ->generateToken ($ data );
172
+
173
+ setcookie (self ::COOKIE_PREFIX . $ this ->suffix , $ token );
174
+
175
+ return true ;
176
+ }
177
+
178
+ public function serializeSessionData ($ array )
179
+ {
180
+ $ result = '' ;
181
+ foreach ($ array as $ key => $ value ) {
182
+ $ result .= $ key . "| " . serialize ($ value );
183
+ }
184
+
185
+ return $ result ;
186
+ }
187
+
188
+ public function unSerializeSessionData ($ session_data )
189
+ {
190
+ $ return_data = array ();
191
+ $ offset = 0 ;
192
+ while ($ offset < strlen ($ session_data )) {
193
+ if (!strstr (substr ($ session_data , $ offset ), "| " )) {
194
+ throw new \Exception ("invalid data, remaining: " . substr ($ session_data , $ offset ));
195
+ }
196
+ $ pos = strpos ($ session_data , "| " , $ offset );
197
+ $ num = $ pos - $ offset ;
198
+ $ varname = substr ($ session_data , $ offset , $ num );
199
+ $ offset += $ num + 1 ;
200
+ $ data = unserialize (substr ($ session_data , $ offset ));
201
+ $ return_data [$ varname ] = $ data ;
202
+ $ offset += strlen (serialize ($ data ));
203
+ }
204
+
205
+ return $ return_data ;
206
+ }
207
+ }
0 commit comments