Add browser authentication

Use getAppLink and getDeviceAuthToken to enable Sonos listeners to authenticate with your service using a web browser. The following is an example flow that the user will go through:

Follow the steps below to enable this flow:

  1. Respond to getAppLink to establish the household with your service Sonos calls getAppLink to send information about the household to your service. Your service returns information that enables the user to authenticate with your service.
  2. Respond to getDeviceAuthToken to associate the user with the household Sonos calls getDeviceAuthToken to acquire a token from your service. Your service establishes the token to represent the association between the authenticated user and the Sonos household. Sonos and your service then ensure authentication by exchanging the token.

Respond to getAppLink

Respond to getAppLink to establish the household with your service. The getAppLink call is the first call in the authentication process. It sends the household ID and other information to your music service. The household ID identifies the user's Sonos system. To support multiple accounts, Sonos seeds the household ID to function as a unique ID for each account. The first account uses the household ID, while subsequent accounts have extra information appended.

The following process flow shows the case where the user already has an account with your service and you are supplying a browser web page from which the user will authenticate.

  1. The user selects Add Account.
  2. The Sonos app sends a getAppLink request to your service. The householdId identifies the user's Sonos system. This first example uses only the householdId parameter. We'll discuss the other parameters later in Add app authentication.
  3. Your service provides an ID, from the Localization Resources page in your Integration Submission Form, in appUrlStringId. The ID identifies the string label for the button the user selects for launching the web page. (See also localization.)
  4. Obtain the link code from your authorization service. Sonos passes the link code back to your service later with getDeviceAuthToken when it requests authorization tokens.
  5. Your service provides the Web page URL in regUrl and encodes the link code as a parameter of the URL.
  6. Return results for getAppLink are shown below.

A getAppLink request from the Sonos app might look like this:

CONNECTION: close
ACCEPT-ENCODING: gzip
HOST: smapi.acme.com
USER-AGENT: Linux UPnP/1.0 Sonos/31.3-20100 (ICRU_iPhone3,1); iOS/Version 6.1.3 (Build 10B329)
CONTENT-LENGTH: 520
CONTENT-TYPE: text/xml; charset="utf-8"
SOAPACTION: "http://www.sonos.com/Services/1.1#getAppLink"
 
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns="http://www.sonos.com/Services/1.1">
   <soapenv:Header>
      <ns:context>
      </ns:context>
      <ns:credentials>
      </ns:credentials>
   </soapenv:Header>
   <soapenv:Body>
      <ns:getAppLink>
         <ns:householdId>Sonos_ghsAflSonosakevCzmxcmFhN7pN</ns:householdId>
         <ns:hardware>iPhone8,2</ns:hardware>
         <ns:osVersion>Version 9.3.3 (Build 13G34)</ns:osVersion>
         <ns:sonosAppName>ICRU_iPhone8,2</ns:sonosAppName>
         <ns:callbackPath>sonos://x-callback-url/addAccount?state=sid%3D61703%26OAuthDeviceID%3DSonos_ghsAflSonosakevCzmxcmFhN7pN%26callbackPath%3D%2FaddAccount</ns:callbackPath>
      </ns:getAppLink>
   </soapenv:Body>
</soapenv:Envelope>

See getAppLink in the reference for descriptions of all parameters and return elements.

The simplest form of a getAppLink response is an authorizeAccount element containing the following minimum elements for a browser authentication response:

  • appUrlStringId— An ID for the string that labels the button the user presses to launch the browser.
  • deviceLink — The authorization service needs to generate a unique link code for the user. For security purposes, we recommend giving the link code a short lifespan (1 hour or less) and do not reuse them. You are free to use any format you wish for link codes but there is a strict 32 character limit on length. Your service stores and associates the link code with the household ID.
    • regUrl — The URL to your web page where the user logs in to authenticate.
    • linkCode — The generated link code from the authorization service, which represents this user's household in your music service.
    • showLinkCode — A boolean flag indicating whether the Sonos app should display the link code.
    • linkDeviceId — (Optional) A token, hidden from the user to prevent token phishing.

The linkDeviceId gives your service an extra, hidden, token to use to verify that the device you originally gave the token to is the same device sending you the request. The player does not share this with the user and sends it back in the getDeviceAuthToken request, which the player sends to your secure endpoint.

In most cases, you should encode the link code as a linkCode parameter in the regUrl and set showLinkCode to false. When the user opens the URL, your Web page can extract the link code. If you do not encode the link code in the regUrl, set showLinkCode to true. This causes the Sonos app to display the link code for the user so that they can later enter it on your authentication Web page.

Your service should send a response something like the following for browser authentication (HTTP headers omitted):

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns="http://www.sonos.com/Services/1.1">
   <s:Body>
      <ns:getAppLinkResponse>
         <ns:getAppLinkResult xsi:type="appLinkResult" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
            <ns:authorizeAccount>
               <ns:appUrlStringId>SIGN_IN</ns:appUrlStringId>
               <ns:deviceLink>
                  <ns:regUrl>https://oauth.acme.com/deviceLink/home?linkCode=AKVS3FHEAUCXAQKLkMA</ns:regUrl>
                  <ns:linkCode>AKVS3FHEAUCXAQKLkMA</ns:linkCode>
                  <ns:showLinkCode>false</ns:showLinkCode>
               </ns:deviceLink>
            </ns:authorizeAccount>
         </ns:getAppLinkResult>
      </ns:getAppLinkResponse>
   </s:Body>
</s:Envelope>

Respond to getDeviceAuthToken

Respond to getDeviceAuthToken to associate the user with the household. The getDeviceAuthToken call sends the household ID and link code (from the getAppLink response) to your service to get the authorization token. Processing of getDeviceAuthToken depends on what results your service returns for getAppLink.

  • App authentication - If your service returns an app URL in the appUrl element of getAppLink and the user has the app installed, processing uses app authentication.
  • Browser authentication - If your service does not return the appUrl element for getAppLink, the processing uses browser authentication with the URL from the regUrl element of getAppLink.

⚠️

Missing app behavior

If your service does return appUrl but the user does not have the corresponding app installed, the Sonos app will use values from failureStringId and failureURL to display a page directing the user to download the app.

The following summarizes the differences between app authentication and browser authentication for getDeviceAuthToken processing:

For app authentication, after your app completes authentication and obtains user authorization, your app uses inter-app communication to call back and reestablish control to the Sonos app (shown in blue). Because a Web page cannot communicate back to the Sonos app after obtaining user authorization, the best your Web page can do is display to the user instructions to return to the Sonos app.

The rest of this section describes the details of how to respond to getDeviceAuthToken for browser authentication. See Add app authenticationfor the response for app authentication.

Note that the user has to manually authenticate before the authorization service can establish the authorization token. Therefore, your service may not be ready to provide the authorization token when it receives the getDeviceAuthToken request. The Sonos app sends the call repeatedly, polling for the response until the call either succeeds or fails. Thus there are three possible responses your service needs to provide for getDeviceAuthToken requests: retry, success, or failure.

The following process flow continues with the case where the user already has an account with your service and your service supplied a Web page from which the user authenticates. After getAppLink returns, the user chooses to add the account.

  1. The Sonos app sends a getDeviceAuthToken request to your service with the householdId and the linkCode parameters. The Sonos app will regularly poll with this request for up to seven minutes until it receives a success response from your service, which indicates the user's account is authenticated. Until then, your service continues to return a retry response.

  2. The Sonos app starts the Web browser, which presents the Web page (regUrl) to the user.

  3. The user enters their account credentials for your service and follows your authentication process in the browser.

  4. Your Web server obtains authorization from your authorization service.

  5. Your Web page tells the user to switch back to using the Sonos app.

  6. Your service gets the authorization token for this link code from your authorization service.

  7. Your service sets the following additional values:

    • A private key for managing refresh tokens.
    • A hash code value your service uses to identify this user.
    • An optional nickname from the user's account on your service so that the Sonos app can pre-populate the name on the user's system.
  8. Your service finally returns the success response for a getDeviceAuthToken request.

  9. The Sonos app communicates with a Sonos player, which first confirms the user account is not a duplicate, and then creates the account for the Sonos household. The Sonos household is then able to query your service with the link code to get the user-specific authorization token, which is then stored on the user's Sonos system as their authorization information.

  10. Your service is added to the user's Sonos household.

Finally, the user sees a screen that indicates setup is complete, where they can change the nickname for their account.

A getDeviceAuthToken request from the Sonos app might look like the following. See getDeviceAuthToken in the reference for descriptions of all parameters and return elements.

POST https://mymusicservice.example.com/smapi HTTP/1.1
Accept-Encoding: gzip,deflate
Content-Type: text/xml;charset=UTF-8
SOAPAction: "http://www.sonos.com/Services/1.1#getDeviceAuthToken"
Content-Length: 1057
Host: example.com
 
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns="http://www.sonos.com/Services/1.1">
   <soap:Header>
      <ns:credentials>
         <ns:deviceId>deviceId32578</ns:deviceId>
         <ns:deviceProvider>Sonos</ns:deviceProvider>
      </ns:credentials>
   </soap:Header>
   <soap:Body>
      <ns:getDeviceAuthToken>
         <ns:householdId>householdId653482</ns:householdId>
         <ns:linkCode>8c047510296b11e5a2cb0800200c9a66</ns:linkCode>
      </ns:getDeviceAuthToken>
   </soap:Body>
</soap:Envelope>

Retry response to getDeviceAuthToken

While your service waits for the user to manually log in through the browser, it should provide the following SOAP fault response to the getDeviceAuthToken call for a few minutes. For error handling, see Handle auth errors.

📘

General error handling requirements

Sonos authentication errors have different requirements than general errors. See Error handling for general error handling.

  • faultcode — The value should be Client.NOT_LINKED_RETRY.
  • faultstring — A message indicating the token is not available.The message in this string is placed in the Sonos logs.
  • ExceptionInfo — A message indicating the response the Sonos app should take. This message string is placed in the Sonos logs.
  • SonosError — This value must be 5 in order for the Sonos app to respond correctly. Your string tables require a corresponding custom error message with this value and an associated error message string. However, the content of the message string is not displayed or stored anywhere.

For example:

HTTP/1.1 500 Internal Server Error
Content-Type: text/xml; charset=utf8;
Content-Length: 305
 
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns="http://www.sonos.com/Services/1.1">
   <soap:Body>
      <soap:Fault>
         <faultcode>Client.NOT_LINKED_RETRY</faultcode>
         <faultstring>Access token not found, retry</faultstring>
         <detail>
            <ns:ExceptionInfo>Retry token request.</ns:ExceptionInfo>
            <ns:SonosError>5</ns:SonosError>
         </detail>
      </soap:Fault>
   </soap:Body>
</soap:Envelope>

Success response to getDeviceAuthToken

After the user successfully logs in, your authorization service can create the authorization token. You can use any format you wish for authorization tokens using up to 2048 characters. Your service must be able to decode the user from the token so that it can perform actions on the correct account, such as setting a user favorite. if a user connects to more than one Sonos household, your service must use a different token to represent that user-household combination.

Then your service should send a success response with the following elements. See also getDeviceAuthToken in the reference.

  • authToken — Enter the authorization token that your service uses to identify the user at this household.
  • privateKey — Enter the private key tied to the authorization token. Use this to support automatic refreshing of tokens. For more see the section on Refreshing Authorization Tokens in Use authentication tokens. If you do not implement refresh tokens, simply include a meaningless string for this value. The string is passed back to your service but not expected to have any meaning or be processed.
  • userIdHashCode — Enter an ID for the user. This should not contain any identifiable information.
  • userInfo — An element in which you can enter a user nickname if your service supports it.

For example:

HTTP/1.1 200 OK
Content-Type: text/xml; charset=utf-8
Content-Length: 247
 
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns="http://www.sonos.com/Services/1.1">
   <soap:Body>
      <ns:getDeviceAuthTokenResponse>
         <ns:getDeviceAuthTokenResult>
            <ns:authToken>faf7a000296b11e5a2cb0800200c9a661a2cab50296c11e5a2cb0800200c9a66</ns:authToken>
            <ns:privateKey>alwaysReauthenticate</ns:privateKey>
         </ns:getDeviceAuthTokenResult>
      </ns:getDeviceAuthTokenResponse>
   </soap:Body>
</soap:Envelope>