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
- Choose a unique app name, like “My Cool Plex App”
- Check storage for your app’s Client Identifier; generate and store one if none is present.
- Check storage for the user’s Access Token; if present, verify its validity and carry on.
- If an Access Token is missing or invalid, generate a PIN, and store its
id
. - Construct an Auth App url and send the user’s browser there to authenticate.
- 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>'