3 * Session API: WP_Session_Tokens class
11 * Abstract class for managing user session tokens.
15 abstract class WP_Session_Tokens {
27 * Protected constructor.
31 * @param int $user_id User whose session to manage.
33 protected function __construct( $user_id ) {
34 $this->user_id = $user_id;
38 * Get a session token manager instance for a user.
40 * This method contains a filter that allows a plugin to swap out
41 * the session manager for a subclass of WP_Session_Tokens.
47 * @param int $user_id User whose session to manage.
49 final public static function get_instance( $user_id ) {
51 * Filters the session token manager used.
55 * @param string $session Name of class to use as the manager.
56 * Default 'WP_User_Meta_Session_Tokens'.
58 $manager = apply_filters( 'session_token_manager', 'WP_User_Meta_Session_Tokens' );
59 return new $manager( $user_id );
63 * Hashes a session token for storage.
68 * @param string $token Session token to hash.
69 * @return string A hash of the session token (a verifier).
71 final private function hash_token( $token ) {
72 // If ext/hash is not present, use sha1() instead.
73 if ( function_exists( 'hash' ) ) {
74 return hash( 'sha256', $token );
76 return sha1( $token );
81 * Get a user's session.
86 * @param string $token Session token
87 * @return array User session
89 final public function get( $token ) {
90 $verifier = $this->hash_token( $token );
91 return $this->get_session( $verifier );
95 * Validate a user's session token as authentic.
97 * Checks that the given token is present and hasn't expired.
102 * @param string $token Token to verify.
103 * @return bool Whether the token is valid for the user.
105 final public function verify( $token ) {
106 $verifier = $this->hash_token( $token );
107 return (bool) $this->get_session( $verifier );
111 * Generate a session token and attach session information to it.
113 * A session token is a long, random string. It is used in a cookie
114 * link that cookie to an expiration time and to ensure the cookie
115 * becomes invalidated upon logout.
117 * This function generates a token and stores it with the associated
118 * expiration time (and potentially other session information via the
119 * {@see 'attach_session_information'} filter).
124 * @param int $expiration Session expiration timestamp.
125 * @return string Session token.
127 final public function create( $expiration ) {
129 * Filters the information attached to the newly created session.
131 * Could be used in the future to attach information such as
132 * IP address or user agent to a session.
136 * @param array $session Array of extra data.
137 * @param int $user_id User ID.
139 $session = apply_filters( 'attach_session_information', array(), $this->user_id );
140 $session['expiration'] = $expiration;
143 if ( !empty( $_SERVER['REMOTE_ADDR'] ) ) {
144 $session['ip'] = $_SERVER['REMOTE_ADDR'];
148 if ( ! empty( $_SERVER['HTTP_USER_AGENT'] ) ) {
149 $session['ua'] = wp_unslash( $_SERVER['HTTP_USER_AGENT'] );
153 $session['login'] = time();
155 $token = wp_generate_password( 43, false, false );
157 $this->update( $token, $session );
163 * Update a session token.
168 * @param string $token Session token to update.
169 * @param array $session Session information.
171 final public function update( $token, $session ) {
172 $verifier = $this->hash_token( $token );
173 $this->update_session( $verifier, $session );
177 * Destroy a session token.
182 * @param string $token Session token to destroy.
184 final public function destroy( $token ) {
185 $verifier = $this->hash_token( $token );
186 $this->update_session( $verifier, null );
190 * Destroy all session tokens for this user,
191 * except a single token, presumably the one in use.
196 * @param string $token_to_keep Session token to keep.
198 final public function destroy_others( $token_to_keep ) {
199 $verifier = $this->hash_token( $token_to_keep );
200 $session = $this->get_session( $verifier );
202 $this->destroy_other_sessions( $verifier );
204 $this->destroy_all_sessions();
209 * Determine whether a session token is still valid,
210 * based on expiration.
215 * @param array $session Session to check.
216 * @return bool Whether session is valid.
218 final protected function is_still_valid( $session ) {
219 return $session['expiration'] >= time();
223 * Destroy all session tokens for a user.
228 final public function destroy_all() {
229 $this->destroy_all_sessions();
233 * Destroy all session tokens for all users.
239 final public static function destroy_all_for_all_users() {
240 $manager = apply_filters( 'session_token_manager', 'WP_User_Meta_Session_Tokens' );
241 call_user_func( array( $manager, 'drop_sessions' ) );
245 * Retrieve all sessions of a user.
250 * @return array Sessions of a user.
252 final public function get_all() {
253 return array_values( $this->get_sessions() );
257 * This method should retrieve all sessions of a user, keyed by verifier.
262 * @return array Sessions of a user, keyed by verifier.
264 abstract protected function get_sessions();
267 * This method should look up a session by its verifier (token hash).
272 * @param string $verifier Verifier of the session to retrieve.
273 * @return array|null The session, or null if it does not exist.
275 abstract protected function get_session( $verifier );
278 * This method should update a session by its verifier.
280 * Omitting the second argument should destroy the session.
285 * @param string $verifier Verifier of the session to update.
286 * @param array $session Optional. Session. Omitting this argument destroys the session.
288 abstract protected function update_session( $verifier, $session = null );
291 * This method should destroy all session tokens for this user,
292 * except a single session passed.
297 * @param string $verifier Verifier of the session to keep.
299 abstract protected function destroy_other_sessions( $verifier );
302 * This method should destroy all sessions for a user.
307 abstract protected function destroy_all_sessions();
310 * This static method should destroy all session tokens for all users.
316 public static function drop_sessions() {}