@@ -192,8 +192,8 @@ class WT_API AuthTokenResult
192192
193193 /* ! \brief Returns a new token for this user.
194194 *
195- * An authentication token can be used only once, and needs to be
196- * replaced by a new token .
195+ * Returns the empty string if there is no new token. See
196+ * AuthService::authTokenUpdateEnabled() .
197197 *
198198 * The returned token is valid only if the state() == AuthTokenState::Valid.
199199 */
@@ -203,6 +203,8 @@ class WT_API AuthTokenResult
203203 *
204204 * This returns the token validity in seconds.
205205 *
206+ * Returns -1 if there is no new token, or result() != Valid.
207+ *
206208 * \sa newToken()
207209 */
208210 int newTokenValidity () const ;
@@ -331,6 +333,32 @@ class WT_API AuthService
331333 */
332334 bool authTokensEnabled () const { return authTokens_; }
333335
336+ /* ! \brief Set whether processAuthToken() updates the auth token
337+ *
338+ * If this option is enabled, processAuthToken() will replace the auth token
339+ * with a new token. This is a bit more secure, because an auth token can
340+ * only be used once. This is enabled by default.
341+ *
342+ * However, this means that if a user concurrently opens multiple sessions within
343+ * the same browsers (e.g. multiple tabs being restored at the same time)
344+ * or refreshes before they receive the new cookie, the user will be logged out,
345+ * unless the AbstractUserDatabase implementation takes this into account
346+ * (e.g. keeps the old token valid for a little bit longer)
347+ *
348+ * The default Dbo UserDatabase does not handle concurrent token updates well,
349+ * so disable this option if you want to prevent that issue.
350+ *
351+ * \sa processAuthToken()
352+ * \sa authTokenUpdateEnabled()
353+ */
354+ void setAuthTokenUpdateEnabled (bool enabled) { authTokenUpdateEnabled_ = enabled; }
355+
356+ /* ! \brief Returns whether the auth token is updated
357+ *
358+ * \sa setAuthTokenUpdateEnabled()
359+ */
360+ bool authTokenUpdateEnabled () const { return authTokenUpdateEnabled_; }
361+
334362 /* ! \brief Returns the authentication token cookie name.
335363 *
336364 * This is the default cookie name used for storing the authentication
@@ -380,8 +408,11 @@ class WT_API AuthService
380408 /* ! \brief Processes an authentication token.
381409 *
382410 * This verifies an authentication token, and considers whether it matches
383- * with a token hash value stored in database. If it matches, the token
384- * is removed and a new token is created for the identified user.
411+ * with a token hash value stored in database. If it matches and auth token
412+ * update is enabled, the token is updated with a new hash.
413+ *
414+ * \sa setAuthTokenUpdateEnabled()
415+ * \sa AbstractUserDatabase::updateAuthToken()
385416 */
386417 virtual AuthTokenResult processAuthToken (const std::string& token,
387418 AbstractUserDatabase& users) const ;
@@ -585,6 +616,7 @@ class WT_API AuthService
585616 std::string redirectInternalPath_;
586617
587618 bool authTokens_;
619+ bool authTokenUpdateEnabled_;
588620 int authTokenValidity_; // minutes
589621 std::string authTokenCookieName_;
590622 std::string authTokenCookieDomain_;
0 commit comments