A server that handles the process of retrieving the authorization information and refreshing tokens for the Spotify web API on behalf of your frontend app. Supports the Client Credentials Flow, Authorization Code Flow, and Authorization Code Flow with Proof Key for Code Exchange.
Can be run as a local server directly from Xcode. It will run on http://127.0.0.1:7000
.
This sever can be used with SpotifyAPI. See Using a Backend Server to Retrieve the Authorization Information for more information.
Can also be used with the Spotify iOS SDK. Assign /authorization-code-flow/retrieve-tokens to the "tokenSwapURL" and /authorization-code-flow/refresh-tokens to "tokenRefreshURL".
Requires the following environment variables:
CLIENT_ID
: Your client id from Spotify.CLIENT_SECRET
: Your client secret from Spotify.REDIRECT_URI
: The redirect URI. Can be omitted if this value is sent in the body of requests to the /authorization-code-flow/retrieve-tokens or /authorization-code-flow-pkce/retrieve-tokens endpoints. If both are present, then the value sent in the body of the request takes precedence. If you are using this server with the Spotify iOS SDK, then you must set this value, as it will not be sent in the body of the request to the /authorization-code-flow/retrieve-tokens endpoint.SECRET_KEY
: A randomly generated string that is used to generate a key for encryption. No specific length is required, but generally it should be at least 20 characters. This key is used to encrypt and decrypt the refresh token returned by Spotify. Warning: If you change this value, then any previously-retrieved authorization information will be invalidated.LOG_LEVEL
: Not required, but can be used to change the log level of the loggers used by Vapor (but not the ones used bySpotifyAPI
). See here for more information. See here for how to retrieve the logs from Heroku.
This server is pre-configured for deployment to Heroku (although any platform can be used).
One-Click Deployment
Manual Deployment
First, sign up for a Heroku account, install the command-line tool, login, and create a Heroku application, as described here. Clone this repository and set it as the working directory. Then, run the following command:
heroku git:remote -a [app name]
where app name
is the name of the application that you just created on Heroku. This command adds a custom remote to your repository called heroku
; pushing to it causes your app to be deployed.
Next, set the buildpack to teach heroku how to deal with vapor:
heroku buildpacks:set vapor/vapor
Finally, deploy to Heroku by running the following:
git push heroku main
See here for how to configure the above-mentioned environment variables on heroku.
This server is also available as a docker image in the Amazon ECR Public Gallery. You can sign up for an AWS account here. Create an App Runner service here. Choose "Container registry" for "Repository type" and "Amazon ECR Public" for "Provider". For "Container image URI," use public.ecr.aws/h4z3r8p2/spotify-api-server:latest
. Then, click next. Configure the environment variables as described above. For "Port," use 8080
. Follow the prompts to create the service.
Read more about App Runner here.
Returns the text "success". Used to indicate that the server is online.
Retrieves the authorization information for the Client Credentials Flow.
A request to this endpoint can be made by ClientCredentialsFlowProxyBackend.makeClientCredentialsTokensRequest()
. Assign this endpoint to ClientCredentialsFlowProxyBackend.tokensURL
.
Request
Header: Content-Type: application/x-www-form-urlencoded
The body must contain the following in x-www-form-urlencoded format:
Request Body Parameter | Value |
---|---|
grant_type | client_credentials |
See ClientCredentialsTokensRequest
, which can be used to encode this data.
Response
Header: Content-Type: application/json
Returns the authorization information as JSON data that can be decoded into AuthInfo
. The accessToken
and expirationDate
(which can be decoded from the "expires_in" JSON key) properties should be non-nil
. For example:
{
"access_token": "NgCXRKc...MzYjw",
"token_type": "bearer",
"expires_in": 3600,
}
Read more at the Spotify web API reference.
Retrieves the authorization information for the Authorization Code Flow.
A request to this endpoint can be made by AuthorizationCodeFlowProxyBackend.requestAccessAndRefreshTokens(code:redirectURIWithQuery:)
. Assign this endpoint to AuthorizationCodeFlowProxyBackend.tokensURL
.
Request
Header: Content-Type: application/x-www-form-urlencoded
The body must contain the following in x-www-form-urlencoded format:
Request Body Parameter | Value |
---|---|
grant_type | authorization_code |
code | The authorization code returned from the initial request to the /authorize endpoint. |
redirect_uri | The redirect URI, which must match the value your app supplied when requesting the authorization code. Can be omitted if this value is stored in the REDIRECT_URI environment variable. |
See ProxyTokensRequest
, which can be used to encode this data.
Response
Header: Content-Type: application/json
Returns the authorization information as JSON data that can be decoded into AuthInfo
. The accessToken
,refreshToken
, and expirationDate
(which can be decoded from the "expires_in" JSON key) properties should be non-nil
. For example:
{
"access_token": "NgCXRK...MzYjw",
"token_type": "Bearer",
"scope": "user-read-private user-read-email",
"expires_in": 3600,
"refresh_token": "NgAagA...Um_SHo"
}
Read more at the Spotify web API reference.
Refreshes the access token for the Authorization Code Flow.
A request to this endpoint can be made by AuthorizationCodeFlowProxyBackend.refreshTokens(refreshToken:)
. Assign this endpoint to AuthorizationCodeFlowProxyBackend.tokenRefreshURL
.
Request
Header: Content-Type: application/x-www-form-urlencoded
The body must contain the following in x-www-form-urlencoded format:
Request Body Parameter | Value |
---|---|
grant_type | refresh token |
refresh_token | The refresh token returned from the authorization code exchange. |
See RefreshTokensRequest
, which can be used to encode this data.
Response
Header: Content-Type: application/json
Returns the authorization information as JSON data that can be decoded into AuthInfo
. The accessToken
and expirationDate
(which can be decoded from the "expires_in" JSON key) properties should be non-nil
. For example:
{
"access_token": "NgCXRK...MzYjw",
"token_type": "Bearer",
"scope": "user-read-private user-read-email",
"expires_in": 3600
}
Read more at the Spotify web API reference.
Retrieves the authorization information for the Authorization Code Flow with Proof Key for Code Exchange.
A request to this endpoint can be made by AuthorizationCodeFlowPKCEProxyBackend.requestAccessAndRefreshTokens(code:codeVerifier:redirectURIWithQuery:)
. Assign this endpoint to AuthorizationCodeFlowPKCEProxyBackend.tokensURL
.
Request
Header: Content-Type: application/x-www-form-urlencoded
The body must contain the following in x-www-form-urlencoded format:
Request Body Parameter | Value |
---|---|
grant_type | authorization_code |
code | The authorization code returned from the initial request to the /authorize endpoint. |
coder verifier | The code verifier that you generated when creating the authorization URL |
redirect_uri | The redirect URI, which must match the value your app supplied when requesting the authorization code. Can be omitted if this value is stored in the REDIRECT_URI environment variable. |
See ProxyPKCETokensRequest
, which can be used to encode this data.
Response
Header: Content-Type: application/json
Returns the authorization information as JSON data that can be decoded into AuthInfo
. The accessToken
,refreshToken
, and expirationDate
(which can be decoded from the "expires_in" JSON key) properties should be non-nil
. For example:
{
"access_token": "NgCXRK...MzYjw",
"token_type": "Bearer",
"scope": "user-read-private user-read-email",
"expires_in": 3600,
"refresh_token": "NgAagA...Um_SHo"
}
Read more at the Spotify web API reference.
Refreshes the access token for the Authorization Code Flow with Proof Key for Code Exchange.
A request to this endpoint can be made by AuthorizationCodeFlowPKCEProxyBackend.refreshTokens(refreshToken:)
. Assign this endpoint to AuthorizationCodeFlowPKCEProxyBackend.tokenRefreshURL
.
Request
Header: Content-Type: application/x-www-form-urlencoded
The body must contain the following in x-www-form-urlencoded format:
Request Body Parameter | Value |
---|---|
grant_type | refresh token |
refresh_token | The refresh token returned from the authorization code exchange. |
See ProxyPKCERefreshTokensRequest
, which can be used to encode this data.
Response
Header: Content-Type: application/json
This method returns the authorization information as JSON data that can be decoded into AuthInfo
. The accessToken
, refreshToken
, and expirationDate
(which can be decoded from the "expires_in" JSON key) properties should be non-nil
. For example:
{
"access_token": "NgCXRK...MzYjw",
"token_type": "Bearer",
"scope": "user-read-private user-read-email",
"expires_in": 3600,
"refresh_token": "NgAagA...Um_SHo"
}
Read more at the Spotify web API reference.
Any error that is received from the Spotify web API, along with the headers and status code, are forwarded directly to the client, as SpotifyAPI already knows how to decode these errors. Therefore, do not attempt to decode these errors yourself. If this server encounters an error (e.g., the request body could not be decoded into the expected type, or the refresh token could not be encrypted/decrypted), then the status code will be in the 4xx range, the headers will contain the "Content-Type: application/json" header, and the response body will be a JSON object with the following keys:
Key | Type | Value |
---|---|---|
error | Boolean | Always set to true to disambiguate this response from the JSON payload of a successful response. |
reason | String | A short description of the cause of this error. |