Authenticating with Plex

Authenticating with Plex

Quick Start

You’re developing an app that needs access to a user’s Plex account. To do this, you’ll need to get access to the user’s Access Token. This document details how to check whether an Access Token is valid, and how to obtain a new one.

High-level Steps

  1. Choose a unique app name, like “My Cool Plex App”
  2. Check storage for your app’s Client Identifier; generate and store one if none is present.
  3. Check storage for the user’s Access Token; if present, verify its validity and carry on.
  4. If an Access Token is missing or invalid, generate a PIN, and store its id.
  5. Construct an Auth App url and send the user’s browser there to authenticate.
  6. After authentication, check the PIN’s id to obtain and store the user’s Access Token.

Detailed Steps

Choose a unique app name

The app name you choose will be visible in the user’s Authorized Devices view. The name you choose should be different from any existing Plex products.

Generate a Client Identifier

The Client Identifier identifies the specific instance of your app. A random string or UUID is sufficient here. There are no hard requirements for Client Identifier length or format, but once one is generated the client should store and re-use this identifier for subsequent requests.

Verify stored Access Token validity

You can check whether a user’s stored Access Token is valid by requesting user info from the plex.tv API and examining the HTTP status code of the response.

$ curl -X GET https://plex.tv/api/v2/user \
  -H 'accept: application/json' \
  -d 'X-Plex-Product=My Cool Plex App' \
  -d 'X-Plex-Client-Identifier=<clientIdentifier>' \
  -d 'X-Plex-Token=<userToken>'
HTTP Status Code
200 Access Token is valid
401 Access Token is invalid

If an Access Token is invalid, it should be discarded, and new one should be obtained through the authentication process.

If plex.tv cannot be reached, or if you receive any other status code it indicates an error state, but does not indicate an invalid Access Token.

Generate a PIN

To sign a user in, the app must create a time-limited PIN. The user is then led through a process to “claim” the PIN, associating it with their account and granting the app access to the user’s plex.tv account.

$ curl -X POST https://plex.tv/api/v2/pins \
  -H 'accept: application/json' \
  -d 'strong=true' \
  -d 'X-Plex-Product=My Cool Plex App' \
  -d 'X-Plex-Client-Identifier=<clientIdentifier>'

The response will be a JSON payload; the two important properties are id and code. Store the id locally, and use the code to construct the Auth App url.

{
  "id": 564964751,
  "code": "8lzjqnq8lye02n52jq3fqxf8e",
  …
}

Checking the PIN

There are two primary ways apps interact with the Auth App and the PIN-claiming process; Forwarding and Polling.

Forwarding is used by web-based apps. A user visits your app in their web browser, leaves your app to authenticate with Plex, and returns to your app via a forwardUrl your app provides.

Polling is used by native apps running outside of a web browser. A user indicates their intention to sign-in from within your app, and your app opens a web browser pointing to the Auth App where the user completes sign-in. Your app will periodically poll on the generated PIN until it is claimed, or it expires.

Construct the Auth App url

The user will authenticate with the plex.tv Auth App through their web browser.

If you’re using the Forwarding flow, the user will be returned to your app after authenticating where you’ll be able to check the created PIN to determine the user’s Access Token. The forwardUrl to which the user will be returned can carry the PIN id which needs to be checked on their return to the app.

Auth App urls are encoded as parameters to the url fragment. Practically, this means that your Auth App url will be prefixed with https://app.plex.tv/auth#?; the #? at the end indicates the beginning of the url fragment, and that the content of the fragment afterwards is encoded as url parameter key-values pairs.

Append these parameters to construct the final URL.

Parameter
clientID Your client identifier
code The code from the generated PIN
forwardUrl The url to which the user will be returned after authenticating.
context%5Bdevice%5D%5Bproduct%5D The name of your App; ex “My Cool Plex App”

Example

https://app.plex.tv/auth#?clientID=<clientIdentifier>&code=<pinCode>&context%5Bdevice%5D%5Bproduct%5D=My%20Cool%20Plex%20App&forwardUrl=https%3A%2F%2Fmy-cool-plex-app.com

You can use the qs module to encode all necessary parameters, including the nested context parameter.

const authAppUrl =
  'https://app.plex.tv/auth#?' +
  require('qs').stringify({
    clientID: '<clientIdentifier>',
    code: '<pinCode>',
    forwardUrl: 'https://my-cool-plex-app.com',
    context: {
      device: {
        product: 'My Cool Plex App',
      },
    },
  });

Send user’s browser to constructed Auth App url

Once the Auth App URL has been constructed, send the user’s browser there to authenticate.

Check PIN

If you’re using the Polling flow, your app should periodically (once per second) check the PIN id to determine when the user has signed-in.

If you’re using the Forwarding flow, check the stored PIN id from the PIN creation step. If the PIN has been claimed, the authToken field in the response will contain the user’s Access Token you need to make API calls on behalf of the user. If authentication failed, the authToken field will remain null.

$ curl -X GET 'https://plex.tv/api/v2/pins/<pinID>' \
  -H 'accept: application/json' \
  -d 'code=<pinCode>' \
  -d 'X-Plex-Client-Identifier=<clientIdentifier>'
10 Likes