Use authentication tokens

An authorization token represents a specific user-household combination. Your service generates authorization tokens and passes them back in getDeviceAuthToken responses.

Your application can use the following types of tokens:

  • Non-expiring authentication: This token does not expire. Once a user logs in and authenticates during account setup, they never need to authenticate again. A token is generated representing the user and household to identify the user in other API calls, but the token does not contain names or passwords.
  • Expiring authentication with automatic refresh: Once a user logs in and authenticates during account setup, they never need to authenticate again. However, behind the scenes the user’s authentication is automatically refreshed by the system periodically. A token representing the user and household but not containing names or passwords is generated each time and used to identify the user in other API calls until it expires and a new token is requested.
  • Expiring authentication: When a user authenticates, a specific time limit is set for how long they can remain logged in without manually logging in and authenticating again. A token representing the user and household but not containing names or passwords is generated each time the user logs in and used to identify the user in other API calls until it expires.

After your service completes its response to getDeviceAuthToken, Sonos sets the SOAP header of the rest of the Sonos Music API calls to include a credentials element. This element contains the information needed for your service to continue to authenticate the user for all Sonos API calls. Here are the credentials header sub-elements relevant to authentication:

loginToken — The authentication information for the user making the request. This includes the following sub-elements:

  • token - The initial value is from the user authToken your service returned for the getDeviceAuthToken call made when authenticating the user. Your service manages the token.
  • key - The initial value is from the privateKey your service returned in the same getDeviceAuthToken call. Your service manages the key.
  • householdId - The household ID associated with the user’s current Sonos system. This is the same value the Sonos app sends to your service in the getAppLink request.

For the complete list of credentials sub-elements see the SOAP header section in SOAP requests and responses. The authentication API calls getAppLink and getDeviceAuthToken are the only calls that will not typically contain credentials. (If a Sonos player is in the process of upgrading the authentication mode, getDeviceAuthToken includes credentials as described in Upgrade to OAuth.)


Validate the authentication tokens

Ensure the token supplied is valid for this user. Initially, tokens are created by your authorization service and supplied in the authToken during your service’s getDeviceAuthToken processing. If the token does not correspond to the user, return a SOAP fault to indicate the account is not valid.

In the faultcode subelement, return the value Client.LoginUnauthorized. Add a log message value for the faultstring subelement. This value is used for the Sonos app and player log files. Sonos displays this message in Sonos diagnostics sent by users for debugging and troubleshooting.

<[soap]:Fault> 
    <faultcode>Client.LoginUnauthorized</faultcode> 
    <faultstring>Log-Message</faultstring> 
  </[soap]:Fault>

📘

Optional validation using householdId

As an option, you may also wish to use the householdId to further validate the token.

For example, you may choose to store the householdId value and associate it with the generated token. Your service can later check the stored householdId against the token value provided in future API requests.


Expired authentication tokens

To maintain session security, authentication tokens should have a short life. Sonos offers your service two different ways to refresh tokens for re-authentication without requiring user interaction: SOAP fault and HTTP request.

📘

Credential propagation behavior

Sonos players propagate new credentials to other Sonos players and Sonos apps, but Sonos apps do not.

If your service refreshes a request from a Sonos app (indicated by a device name in the user-agent), you may need to honor the same refresh token when handling a token refresh request from Sonos players.

Private keys and token refresh

A private key is an ID associated with a specific authorization token that allows the token to be refreshed. If you decide to have your authorization tokens expire, you have the choice of requiring the user to log in again once the token expires or to support automatic refresh tokens. If you decide to implement refresh tokens, your service generates new tokens and private keys and passes them back to Sonos in getDeviceAuthToken responses. Details are covered in the section on Refreshing Authorization Tokens in Use authentication tokens.

Initializing refresh tokens

To start using refresh tokens, your authorization service generates a private key and returns it in the privateKey field of your getDeviceAuthToken response along with an authorization token in authToken. Your service needs to maintain an association between the user, the token, and the key. The private key represents the refresh token for this authorization token. You are free to use any format you wish for private keys using up to 2048 characters.

When a user later does something such as a browse request, Sonos includes the token in the header credentials of every API request, as shown below:

<ns:credentials>
  . . .
  <ns:loginToken>
    <ns:token>AUTH-TOKEN<ns:token>
    <ns:householdId>HOUSEHOLD-ID</ns:householdId>
  </ns:loginToken>
</ns:credentials>

🚧

Re-authentication without refresh tokens

If you decide not to support refresh tokens, see Reauthenticate with manual login.

Refreshing expired tokens with SOAP fault

When your service receives an API request, do the following for refresh token processing:

Verify that the token and key in the API request header are valid for this user. If valid, processing is done. If the token and key are not valid, or if the token in the API request header has expired, follow the steps below to refresh the authentication token.

  1. Generate a new authentication token.

  2. Return the Client.TokenRefreshRequired SOAP fault shown below for the current API request:

    <s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns="http://www.sonos.com/Services/1.1">
     <s:Body>
      <s:Fault>
        <faultcode>s:Client.TokenRefreshRequired</faultcode>
        <faultstring>Log-Message</faultstring>
        <detail>
         <ns:refreshAuthTokenResult>
          <ns:authToken>NEW_TOKEN</ns:authToken>
          <ns:privateKey>REFRESH_TOKEN</ns:privateKey>
         </ns:refreshAuthTokenResult>
        </detail>
      </s:Fault>
     </s:Body>
    </s:Envelope>
    
    • Include the new authentication token in authToken.
    • Include the refresh token in privateKey, even if your service has not changed it. You determine the refresh token policy, but you must return it even if it hasn't changed.
  3. This fault causes Sonos to update both the token and key credentials in the header for all subsequent API requests.

  4. Sonos retries the initial API request with the new credentials.

If a token refresh fails, what you return will depend on what behavior you want.

Retry the token refresh process

Return a Server.ServiceUnknownError error with a custom message that asks the user to try the action again in a few moments. See the Custom error messages for details. See Handle auth errors for details on errors specific to authentication.

<soap:Envelope 
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" 
xmlns:ns="http://www.sonos.com/Services/1.1">
   <soap:Body>
       <soap:Fault>
           <faultcode>Server.ServiceUnknownError</faultcode>
           <faultstring>Log-Message</faultstring>
           <detail>
              <ns:ExceptionInfo>Retry in a few moments.
              </ns:ExceptionInfo>
              <ns:SonosError>34</ns:SonosError>
           </detail>
       </soap:Fault>
   </soap:Body>
</soap:Envelope>

Make the user reauthorize

Return a Client.AuthTokenExpired fault. This causes Sonos to give the user a prompt to re-authorize and go through the authorization process again.

<soap-env:Envelope xmlns:soap-env="http://schemas.xmlsoap.org/soap/envelope/">
 <soap-env:Body>
  <soap-env:Fault>
    <faultcode>Client.AuthTokenExpired</faultcode>
    <faultstring>Log-Message</faultstring>
  </soap-env:Fault>
 </soap-env:Body>
</soap-env:Envelope>

Refreshing expired tokens with HTTP request

Sonos calls refreshAuthToken when an HTTP REST request returns a 401 error. The 401 error may indicate an expired authorization token. Your service should send a new authToken and either the existing privateKey or a new one in your response. Sonos will retry the original request using the authToken from your response as the OAuth bearer token in an Authorization header. Sonos will only retry the HTTP request once. If it fails again, Sonos will display a failure message. See REST request for details.

When an HTTP REST request returns a 401 error, the Sonos app sends a refreshAuthToken request like the one shown below. There are no parameters, but Sonos sends the current authToken and privateKey in the header as the token and key elements respectively.

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" xmlns="http://www.sonos.com/Services/1.1">
  <s:Header>
    <credentials>
      <loginToken>
        <token>12345678</token>
        <key>123456789</key>
        <householdId>Sonos_1234EJUN334GGPBMoESCwBABCD</householdId>
      </loginToken>
      <deviceId>B8-E9-37-BD-19-E2:2</deviceId>
      <deviceProvider>Sonos</deviceProvider>
    </credentials>
  </s:Header>
  <s:Body>
    <refreshAuthToken xmlns="http://www.sonos.com/Services/1.1"/>
  </s:Body>
</s:Envelope>

Your service should return a new authToken in your response. You can choose to generate a new privateKey or return the original one. Sonos uses the authToken and privateKey that you send as the token and key values respectively in future SOAP requests. Your service's response should resemble the sample below:

<s:Envelope xmlns:ns="http://www.sonos.com/Services/1.1" xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
  <s:Body>
    <ns:refreshAuthTokenResponse>
      <ns:refreshAuthTokenResult>
        <ns:authToken>1509120972472_3</ns:authToken>
        <ns:privateKey>633728174618</ns:privateKey>
      </ns:refreshAuthTokenResult>
    </ns:refreshAuthTokenResponse>
  </s:Body>
</s:Envelope>

👍

Return the userInfo object if your service supports this capability.

When you don't support refreshAuthToken, listeners see the failure message and have to close the Info View window. Your service can use the SOAP fault method to refresh the token when their system sends another SMAPI request. For example, if the listener selects Info View or browses into a container.

Reauthenticate with manual login

If your service doesn't support refresh tokens at all, the user must manually log in and authenticate again.

When the token expires, return the Client.AuthTokenExpired value in the faultcode subelement in response to getMetadata and getMediaURI to indicate that the user must manually log in and authenticate again. In the faultstring, add a log message for the faultcode.

<[soap]:Fault>
   <faultcode>Client.AuthTokenExpired</faultcode>
   <faultstring>Log-Message</faultstring>
</[soap]:Fault>

📘

Fault response recommendations

You do not need to return this fault in response to getLastUpdate or getMediaMetadata.

When the Sonos speaker sends a getMediaMetadata request and it fails, it does not start playback. The user will also see that playback failed.