62 parent::__construct();
65 'cookieOptions' => [],
70 if ( !isset(
$params[
'priority'] ) ) {
71 throw new \InvalidArgumentException( __METHOD__ .
': priority must be specified' );
76 throw new \InvalidArgumentException( __METHOD__ .
': Invalid priority' );
79 if ( !is_array(
$params[
'cookieOptions'] ) ) {
80 throw new \InvalidArgumentException( __METHOD__ .
': cookieOptions must be an array' );
83 $this->priority =
$params[
'priority'];
84 $this->cookieOptions =
$params[
'cookieOptions'];
86 unset( $this->params[
'priority'] );
87 unset( $this->params[
'cookieOptions'] );
94 'callUserSetCookiesHook' =>
false,
96 $this->
getConfig()->get(
'SessionName' ) ?: $this->
getConfig()->get(
'CookiePrefix' ) .
'_session',
99 $sameSite = $this->
getConfig()->get(
'CookieSameSite' );
100 $this->useCrossSiteCookies = $sameSite !==
null && strcasecmp( $sameSite,
'none' ) === 0;
103 $this->cookieOptions += [
105 'prefix' => $this->
getConfig()->get(
'CookiePrefix' ),
106 'path' => $this->
getConfig()->get(
'CookiePath' ),
107 'domain' => $this->
getConfig()->get(
'CookieDomain' ),
108 'secure' => $this->
getConfig()->get(
'CookieSecure' ) || $this->
getConfig()->get(
'ForceHTTPS' ),
109 'httpOnly' => $this->
getConfig()->get(
'CookieHttpOnly' ),
110 'sameSite' => $sameSite
115 $sessionId = $this->
getCookie( $request, $this->params[
'sessionName'],
'' );
118 'forceHTTPS' => $this->
getCookie( $request,
'forceHTTPS',
'',
false )
121 $info[
'id'] = $sessionId;
122 $info[
'persisted'] =
true;
126 if ( $userId !==
null ) {
129 }
catch ( \InvalidArgumentException $ex ) {
134 if ( $userName !==
null && $userInfo->getName() !== $userName ) {
135 $this->logger->warning(
136 'Session "{session}" requested with mismatched UserID and UserName cookies.',
138 'session' => $sessionId,
141 'cookie_username' => $userName,
142 'username' => $userInfo->getName(),
148 if ( $token !==
null ) {
149 if ( !hash_equals( $userInfo->getToken(), $token ) ) {
150 $this->logger->warning(
151 'Session "{session}" requested with invalid Token cookie.',
153 'session' => $sessionId,
155 'username' => $userInfo->getName(),
159 $info[
'userInfo'] = $userInfo->verified();
160 $info[
'persisted'] =
true;
161 } elseif ( isset( $info[
'id'] ) ) {
162 $info[
'userInfo'] = $userInfo;
168 } elseif ( isset( $info[
'id'] ) ) {
174 $this->logger->debug(
175 'Session "{session}" requested without UserID cookie',
177 'session' => $info[
'id'],
199 if ( $response->headersSent() ) {
201 $this->logger->debug( __METHOD__ .
': Headers already sent' );
211 if ( $this->params[
'callUserSetCookiesHook'] && !$user->isAnon() ) {
212 $this->
getHookRunner()->onUserSetCookies( $user, $sessionData, $cookies );
219 $options[
'secure'] = $this->
getConfig()->get(
'CookieSecure' )
220 || $this->
getConfig()->get(
'ForceHTTPS' );
223 $response->setCookie( $this->params[
'sessionName'], $session->
getId(),
null,
224 [
'prefix' =>
'' ] + $options
227 foreach ( $cookies as $key => $value ) {
228 if ( $value ===
false ) {
229 $response->clearCookie( $key, $options );
232 $expiration = $expirationDuration ? $expirationDuration + time() :
null;
233 $response->setCookie( $key, (
string)$value, $expiration, $options );
240 if ( $sessionData ) {
241 $session->
addData( $sessionData );
247 if ( $response->headersSent() ) {
249 $this->logger->debug( __METHOD__ .
': Headers already sent' );
258 $response->clearCookie(
259 $this->params[
'sessionName'], [
'prefix' =>
'' ] + $this->cookieOptions
262 foreach ( $cookies as $key => $value ) {
263 $response->clearCookie( $key, $this->cookieOptions );
277 if ( $this->
getConfig()->
get(
'ForceHTTPS' ) ) {
288 $expiration = $expirationDuration ? $expirationDuration + time() :
null;
292 $response->setCookie(
'forceHTTPS',
'true', $expiration,
293 [
'prefix' =>
'',
'secure' =>
false ] + $this->cookieOptions );
295 $response->clearCookie(
'forceHTTPS',
296 [
'prefix' =>
'',
'secure' =>
false ] + $this->cookieOptions );
305 if ( $loggedOut + 86400 > time() &&
306 $loggedOut !== (
int)$this->
getCookie( $request,
'LoggedOut', $this->cookieOptions[
'prefix'] )
308 $request->
response()->setCookie(
'LoggedOut', $loggedOut, $loggedOut + 86400,
309 $this->cookieOptions );
317 $this->cookieOptions[
'prefix'] .
'Token',
318 $this->cookieOptions[
'prefix'] .
'LoggedOut',
319 $this->params[
'sessionName'],
325 $name = $this->
getCookie( $request,
'UserName', $this->cookieOptions[
'prefix'] );
326 if ( $name !==
null ) {
327 $name = $this->userNameUtils->getCanonical( $name, UserNameUtils::RIGOR_USABLE );
329 return $name ===
false ? null : $name;
338 $prefix = $this->cookieOptions[
'prefix'];
340 $this->
getCookie( $request,
'UserID', $prefix ),
341 $this->
getCookie( $request,
'UserName', $prefix ),
342 $this->
getCookie( $request,
'Token', $prefix ),
354 protected function getCookie( $request, $key, $prefix, $default =
null ) {
355 if ( $this->useCrossSiteCookies ) {
356 $value = $request->getCrossSiteCookie( $key, $prefix, $default );
358 $value = $request->getCookie( $key, $prefix, $default );
360 if ( $value ===
'deleted' ) {
378 if ( $user->isAnon() ) {
385 'UserID' => $user->getId(),
386 'UserName' => $user->getName(),
387 'Token' => $remember ? (string)$user->getToken() :
false,
400 if ( !$user->isAnon() && $this->params[
'callUserSetCookiesHook'] ) {
402 'wsUserID' => $user->getId(),
403 'wsToken' => $user->getToken(),
404 'wsUserName' => $user->getName(),
412 return wfMessage(
'sessionprovider-nocookies' );
427 return [
'UserID',
'UserName',
'Token' ];
442 $normalExpiration = $this->
getConfig()->get(
'CookieExpiration' );
444 if ( $shouldRememberUser && in_array( $cookieName, $extendedCookies,
true ) ) {
445 $extendedExpiration = $this->
getConfig()->get(
'ExtendedLoginCookieExpiration' );
447 return ( $extendedExpiration !==
null ) ? (int)$extendedExpiration : (int)$normalExpiration;
449 return (
int)$normalExpiration;
wfMessage( $key,... $params)
This is the function for getting translated interface messages.
The User object encapsulates all of the user-specific settings (user_id, name, rights,...
The WebRequest class encapsulates getting at data passed in the URL or via a POSTed form stripping il...
response()
Return a handle to WebResponse style object, for setting cookies, headers and other stuff,...