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 userauthToken
your service returned for thegetDeviceAuthToken
call made when authenticating the user. Your service manages thetoken
.key
- The initial value is from theprivateKey
your service returned in the samegetDeviceAuthToken
call. Your service manages thekey
.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 storedhouseholdId
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.
-
Generate a new authentication token.
-
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.
- Include the new authentication token in
-
This fault causes Sonos to update both the
token
andkey
credentials in the header for all subsequent API requests. -
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
orgetMediaMetadata
.When the Sonos speaker sends a
getMediaMetadata
request and it fails, it does not start playback. The user will also see that playback failed.
Updated 8 months ago