Skip to main content

 API elements

Service API elements from <alias> to <workflow>

<persistent-token>

Summary

The <persistent-token> element represents a persistent authentication token in PageSeeder.

These tokens allow users to maintain authenticated sessions across browser sessions without re-entering credentials. Common use cases include:

  • “Remember me” functionality during login
  • OAuth refresh tokens for third-party applications
  • Special-purpose tokens for password resets and email changes

Usage context

Permitted content<client>, <member>
Permitted parent<persistent-tokens>, <refresh-token-issue>, <refresh-tokens>

Attributes

This element has the following attributes

NameTypeRequiredDescription
dataenumnoOptional information about the token
expiredxs:booleanyesWhether the token has expired or not
expiresxs:dateTimenoWhen the token expires
idxs:longyesThe ID of the token in PageSeeder
issuedxs:dateTimenoWhen the token was issued
lifetimexs:longyesDuration in seconds when the token is valid
scopexs:stringyesScope
tokenxs:stringnoThe actual token value when issued

@data

The data stored against the token depends on its scope.

For “Remember me” tokens, this typically contains the user agent string (browser information) to help identify where the token was issued.

For OAuth tokens, this field might be empty or contain client-specific information.

@expired

Indicates whether the token has expired or not.

@expires

The date and time when the token is no longer valid using ISO8601 date time format.

@issued

The date and time when the token was issued using ISO8601 date time format.

@lifetime

The number of seconds that the persistent token is valid for after it has been issued.

This value is based either on the configuration of the OAuth client when the token was issued, or for special-purpose tokens, on the PageSeeder configuration.

@scope

The OAuth scope for this service.

PageSeeder also uses the scope for some built-in persistent tokens:

Special purpose built-in token scopes
ScopeDefault lifespanDescription
ps:activate-member48 hoursMember activation tokens
ps:change-email12 hoursChange of email address token
ps:remember-me90 daysRemember me
ps:reset-password12 hoursReset password tokens

@token

The actual token value, typically an opaque random 192-bit string formatted as Base64.

For security reasons, this value is only included in the response when the token is initially issued and cannot be retrieved after.

Client applications must store this value securely if they need to use it for subsequent authentication.

Security considerations

  • The @token value is sensitive and must be transmitted and stored securely
  • Tokens are only displayed once upon creation and cannot be retrieved after
  • Applications must validate the @expired attribute before using a token
  • The @data attribute might contain personally identifiable information (such as user agent strings) and must be handled accordingly

Examples

Example 1

This example shows a “Remember me” token issued when a user selects that option during login. The @data attribute contains the user's browser information:

<persistent-token id="25614" scope="ps:remember-me" 
                  lifetime="7776000" 
                  issued="2026-08-31T10:09:32+10:00" 
                  expires="2026-11-29T11:09:32+11:00"
                  expired="false"
                  data="Mozilla/5.0 Firefox/155.0">
  <member id="123" firstname="Alice" surname="Smith" 
          username="asmith" status="activated">
    <fullname>Alice Smith</fullname>
  </member>
</persistent-token>

These tokens are issued the user selects the “Remember me” option.

Example 2

This example shows a refresh token issued to a third-party OAuth client app:

<persistent-token id="2595" scope="openid profile email" 
                  lifetime="2592000" 
                  issued="2026-09-07T13:10:50+10:00"
                  expires="2026-10-07T14:10:50+11:00" expired="false">
  <client id="13" identifier="e7bc4a7c9dd3c42a" 
          requires-consent="false" confidential="true" 
          name="Developer Website (Official)" 
          grant-type="authorization_code" 
          created="2026-09-07T12:27:27+10:00" 
          modified="2026-09-07T14:34:24+10:00" 
          last-token="2026-09-07T13:00:00+10:00" 
          app="Developer" redirect-uri="https://dev.example.org" 
          description="Developer sign-in for the example Website" 
          client-uri="https://dev.example.org" 
          scope="openid profile email"
          access-token-max-age="3600"
          refresh-token-max-age="2592000">
    <member id="3718" firstname="Dev" surname="Example" 
            username="devex" status="disabled">
      <fullname>Dev Example</fullname>
    </member>
  </client>
  <member id="264" firstname="Alice" surname="Smith" 
          username="asmith" status="activated">
    <fullname>Alice Smith</fullname>
  </member>
</persistent-token>

Note the presence of both <client> and <member> elements.

Schema

XML Schema

<xs:element name="persistent-token">
  <xs:complexType>
    <xs:sequence>
      <xs:element ref="client" minOccurs="0" maxOccurs="1"/>
      <xs:element ref="member" minOccurs="0" maxOccurs="1"/>
    </xs:sequence>
    <xs:attribute name="id" type="xs:long" use="required"/>
    <xs:attribute name="scope" type="xs:string" use="required"/>
    <xs:attribute name="lifetime" type="xs:long" use="required"/>
    <xs:attribute name="expired" type="xs:boolean" use="required"/>
    <xs:attribute name="issued" type="xs:dateTime" use="optional"/>
    <xs:attribute name="expires" type="xs:dateTime" use="optional"/>
    <xs:attribute name="token" type="xs:string" use="optional"/>
    <xs:attribute name="data" type="xs:string" use="optional" />
  </xs:complexType>
</xs:element>

Compatibility

No change since initial API release.

Created on , last edited on