mirror of
https://github.com/Sarsoo/Spotify.NET.git
synced 2024-12-23 22:56:25 +00:00
Minor fixes for comprehesion (#507)
Fixed capitalization, spelling, grammar, added gender-neutral language
This commit is contained in:
parent
662b8d0610
commit
300c51db3c
@ -5,12 +5,12 @@ title: Introduction
|
|||||||
|
|
||||||
import useBaseUrl from '@docusaurus/useBaseUrl';
|
import useBaseUrl from '@docusaurus/useBaseUrl';
|
||||||
|
|
||||||
Spotify does not allow unauthorized access to the api. Thus, you need an access token to make requets. This access token can be gathered via multiple schemes, all following the OAuth2 spec. Since it's important to choose the correct scheme for your usecase, make sure you have a grasp of the following terminology/docs:
|
Spotify does not allow unauthorized access to the API. Thus, you need an access token to make requests. This access token can be gathered via multiple schemes, all following the OAuth2 spec. Since it's important to choose the correct scheme for your usecase, make sure you have a grasp of the following terminology/docs:
|
||||||
|
|
||||||
- OAuth2
|
- OAuth2
|
||||||
- [Spotify Authorization Flows](https://developer.spotify.com/documentation/general/guides/authorization-guide/#authorization-code-flow)
|
- [Spotify Authorization Flows](https://developer.spotify.com/documentation/general/guides/authorization-guide/#authorization-code-flow)
|
||||||
|
|
||||||
Since every auth flow also needs an application in the [spotify dashboard](https://developer.spotify.com/dashboard/), make sure you have the necessary values (like `Client Id` and `Client Secret`).
|
Since every auth flow also needs an application in the [Spotify dashboard](https://developer.spotify.com/dashboard/), make sure you have the necessary values (like `Client Id` and `Client Secret`).
|
||||||
|
|
||||||
Then, continue with the docs of the specific auth flows:
|
Then, continue with the docs of the specific auth flows:
|
||||||
|
|
||||||
|
@ -7,7 +7,7 @@ title: Authorization Code
|
|||||||
|
|
||||||
## Existing Web-Server
|
## Existing Web-Server
|
||||||
|
|
||||||
If you are already in control of a Web-Server (like `ASP.NET`), you can start the flow by generating a login uri
|
If you are already in control of a Web-Server (like `ASP.NET`), you can start the flow by generating a login uri:
|
||||||
|
|
||||||
```csharp
|
```csharp
|
||||||
// Make sure "http://localhost:5000" is in your applications redirect URIs!
|
// Make sure "http://localhost:5000" is in your applications redirect URIs!
|
||||||
@ -23,7 +23,7 @@ var uri = loginRequest.ToUri();
|
|||||||
// Redirect user to uri via your favorite web-server
|
// Redirect user to uri via your favorite web-server
|
||||||
```
|
```
|
||||||
|
|
||||||
When the user is redirected to the generated uri, he will have to login with his spotify account and confirm, that your application wants to access his user data. Once confirmed, he will be redirect to `http://localhost:5000` and a `code` parameter is attached to the query. This `code` has to be exchanged for an `access_token` and `refresh_token`:
|
When the user is redirected to the generated uri, they will have to login with their Spotify account and confirm that your application wants to access their user data. Once confirmed, they will be redirected to `http://localhost:5000` and a `code` parameter is attached to the query. This `code` has to be exchanged for an `access_token` and `refresh_token`:
|
||||||
|
|
||||||
```csharp
|
```csharp
|
||||||
// This method should be called from your web-server when the user visits "http://localhost:5000"
|
// This method should be called from your web-server when the user visits "http://localhost:5000"
|
||||||
@ -68,7 +68,7 @@ For a real example, have a look at [Example.ASP](https://github.com/JohnnyCrazy/
|
|||||||
For cross-platform CLI and desktop apps (non `UWP` apps), `Spotify.Web.Auth` can be used to supply a small embedded Web Server for the code retrieval.
|
For cross-platform CLI and desktop apps (non `UWP` apps), `Spotify.Web.Auth` can be used to supply a small embedded Web Server for the code retrieval.
|
||||||
|
|
||||||
:::warning
|
:::warning
|
||||||
You're client secret will be exposed when embedded in a desktop/cli app. This can be abused and is not preffered. If possible, let the user create an application in spotify dashboard or let a server handle the spotify communication.
|
Your client secret will be exposed when embedded in a desktop/CLI app. This can be abused and is not prefered. If possible, let the user create an application in the Spotify dashboard or let a server handle the Spotify communication.
|
||||||
:::
|
:::
|
||||||
|
|
||||||
```csharp
|
```csharp
|
||||||
@ -101,7 +101,7 @@ private static async Task OnAuthorizationCodeReceived(object sender, Authorizati
|
|||||||
);
|
);
|
||||||
|
|
||||||
var spotify = new SpotifyClient(tokenResponse.AccessToken);
|
var spotify = new SpotifyClient(tokenResponse.AccessToken);
|
||||||
// do calls with spotify and save token?
|
// do calls with Spotify and save token?
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -26,7 +26,7 @@ public static async Task Main()
|
|||||||
|
|
||||||
## Request Token On-Demand
|
## Request Token On-Demand
|
||||||
|
|
||||||
You can also use `CredentialsAuthenticator`, which will make sure the spotify instance will always have an up-to-date access token by automatically refreshing the token on-demand.
|
You can also use `CredentialsAuthenticator`, which will make sure the Spotify instance will always have an up-to-date access token by automatically refreshing the token on demand.
|
||||||
|
|
||||||
```csharp
|
```csharp
|
||||||
public static async Task Main()
|
public static async Task Main()
|
||||||
@ -40,6 +40,6 @@ public static async Task Main()
|
|||||||
```
|
```
|
||||||
|
|
||||||
:::info
|
:::info
|
||||||
There is no thread safety guaranteed when using `CredentialsAuthenticator`.
|
Thread safety is not guaranteed when using `CredentialsAuthenticator`.
|
||||||
:::
|
:::
|
||||||
|
|
||||||
|
@ -3,7 +3,7 @@ id: configuration
|
|||||||
title: Configuration
|
title: Configuration
|
||||||
---
|
---
|
||||||
|
|
||||||
To configure the spotify client functionality, the `SpotifyClientConfig` class exists.
|
To configure the Spotify client functionality, the `SpotifyClientConfig` class exists.
|
||||||
|
|
||||||
```csharp
|
```csharp
|
||||||
var config = SpotifyClientConfig.CreateDefault("YourAccessToken");
|
var config = SpotifyClientConfig.CreateDefault("YourAccessToken");
|
||||||
@ -20,7 +20,7 @@ We won't cover every possible configuration in this part, head over to the speci
|
|||||||
|
|
||||||
## HTTPClient Notes
|
## HTTPClient Notes
|
||||||
|
|
||||||
One important part of the configuration is the used HTTPClient. By default, every time when a `SpotifyClientConfig` is instantiated, a new `HTTPClient` is created in the background. For Web Applications which require a lot of different configs due to user based access tokens, it is **not** advised to create a new config from scratch with every HTTP call. Instead, a default (static) config should be used to create a new config with a new access token.
|
One important part of the configuration is the used HTTPClient. By default, every time a `SpotifyClientConfig` is instantiated, a new `HTTPClient` is created in the background. For Web Applications that require a lot of different configs due to user based access tokens, it is **not** advised to create a new config from scratch with every HTTP call. Instead, a default (static) config should be used to create a new config with a new access token.
|
||||||
|
|
||||||
Consider the following HTTP Endpoint:
|
Consider the following HTTP Endpoint:
|
||||||
|
|
||||||
@ -32,7 +32,7 @@ public HttpResult Get()
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
This creates a new `HTTPClient` every time a request is made, which can be quite bad for the performance. Instead we should use a base config and use `WithToken`:
|
This creates a new `HTTPClient` every time a request is made, which can be quite bad for the performance. Instead, we should use a base config and use `WithToken`:
|
||||||
|
|
||||||
```csharp
|
```csharp
|
||||||
// somewhere global/static
|
// somewhere global/static
|
||||||
@ -45,4 +45,4 @@ public HttpResult Get()
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
This way, a single `HTTPClient` will be used. For a real example, checkout the [ASP.NET Example](example_asp.md)
|
This way, a single `HTTPClient` will be used. For a real example, checkout the [ASP.NET Example](example_asp.md).
|
||||||
|
@ -10,11 +10,11 @@ var track = await spotify.Tracks.Get("NotExistingTrackId");
|
|||||||
Console.WriteLine(track.Name);
|
Console.WriteLine(track.Name);
|
||||||
```
|
```
|
||||||
|
|
||||||
When a request fails an `APIException` is thrown. Specific errors may throw a child exception of `APIException`.
|
When a request fails, an `APIException` is thrown. Specific errors may throw a child exception of `APIException`.
|
||||||
|
|
||||||
## APIException
|
## APIException
|
||||||
|
|
||||||
A very general API error. The message is parsed from the API response JSON body and the response is available as public property.
|
A very general API error. The message is parsed from the API response's JSON body and the response is available as a public property.
|
||||||
|
|
||||||
```csharp
|
```csharp
|
||||||
try {
|
try {
|
||||||
@ -29,11 +29,11 @@ try {
|
|||||||
|
|
||||||
## APIUnauthorizedException
|
## APIUnauthorizedException
|
||||||
|
|
||||||
Provides the same properties as `APIException` and occurs, when the access token is expired or not provided. Notice that an access token has to be included in **every** request. Spotify does not allow unauthorized API access.
|
Provides the same properties as `APIException` and occurs when the access token is expired or not provided. Notice that an access token has to be included in **every** request. Spotify does not allow unauthorized API access.
|
||||||
|
|
||||||
## APITooManyRequestsException
|
## APITooManyRequestsException
|
||||||
|
|
||||||
Provides the same properties as `APIException` and occurs, when too many requests has been sent by your application. It also provides the property `TimeSpan RetryAfter`, which maps to the received `Retry-After` Header.
|
Provides the same properties as `APIException` and occurs when too many requests has been sent by your application. It also provides the property `TimeSpan RetryAfter`, which maps to the received `Retry-After` header.
|
||||||
|
|
||||||
```csharp
|
```csharp
|
||||||
try {
|
try {
|
||||||
|
@ -42,6 +42,7 @@ You're now ready to issue your first calls to the Spotify API, a small console e
|
|||||||
|
|
||||||
```csharp
|
```csharp
|
||||||
using System;
|
using System;
|
||||||
|
using System.Threading.Tasks;
|
||||||
using SpotifyAPI.Web;
|
using SpotifyAPI.Web;
|
||||||
|
|
||||||
class Program
|
class Program
|
||||||
|
@ -5,13 +5,13 @@ title: Implicit Grant
|
|||||||
|
|
||||||
import useBaseUrl from '@docusaurus/useBaseUrl';
|
import useBaseUrl from '@docusaurus/useBaseUrl';
|
||||||
|
|
||||||
> Implicit grant flow is for clients that are implemented entirely using JavaScript and running in the resource owner’s browser. You do not need any server-side code to use it. Rate limits for requests are improved but there is no refresh token provided. This flow is described in RFC-6749.
|
> Implicit grant flow is for clients that are implemented entirely using JavaScript and running in the resource owner’s browser. You do not need any server-side code to use it. Rate limits for requests are improved but there is no refresh token provided. This flow is described in [RFC-6749](http://tools.ietf.org/html/rfc6749#section-4.2).
|
||||||
|
|
||||||
This flow is useful for getting a user access token for a short timespan
|
This flow is useful for getting a user access token for a short timespan.
|
||||||
|
|
||||||
## Existing Web-Server
|
## Existing Web-Server
|
||||||
|
|
||||||
If you are already in control of a Web-Server (like `ASP.NET`), you can start the flow by generating a login uri
|
If you are already in control of a Web-Server (like `ASP.NET`), you can start the flow by generating a login uri:
|
||||||
|
|
||||||
```csharp
|
```csharp
|
||||||
// Make sure "http://localhost:5000" is in your applications redirect URIs!
|
// Make sure "http://localhost:5000" is in your applications redirect URIs!
|
||||||
@ -27,7 +27,7 @@ var uri = loginRequest.ToUri();
|
|||||||
// Redirect user to uri via your favorite web-server
|
// Redirect user to uri via your favorite web-server
|
||||||
```
|
```
|
||||||
|
|
||||||
When the user is redirected to the generated uri, he will have to login with his spotify account and confirm, that your application wants to access his user data. Once confirmed, he will be redirect to `http://localhost:5000` and the fragment identifier (`#` part of URI) will contain an access token.
|
When the user is redirected to the generated uri, they will have to login with their Spotify account and confirm that your application wants to access their user data. Once confirmed, they will be redirected to `http://localhost:5000` and the fragment identifier (`#` part of URI) will contain an access token.
|
||||||
|
|
||||||
:::warning
|
:::warning
|
||||||
Note, this parameter is not sent to the server! You need JavaScript to access it.
|
Note, this parameter is not sent to the server! You need JavaScript to access it.
|
||||||
@ -39,7 +39,7 @@ This flow can also be used with custom protocols instead of `http`/`https`. This
|
|||||||
|
|
||||||
<img alt="protocol handlers" src={useBaseUrl('img/auth_protocol_handlers.png')} />
|
<img alt="protocol handlers" src={useBaseUrl('img/auth_protocol_handlers.png')} />
|
||||||
|
|
||||||
The process is very similar, you generate a uri and open it for the user
|
The process is very similar, you generate a uri and open it for the user:
|
||||||
|
|
||||||
```csharp
|
```csharp
|
||||||
// Make sure "spotifyapi.web.oauth://token" is in your applications redirect URIs!
|
// Make sure "spotifyapi.web.oauth://token" is in your applications redirect URIs!
|
||||||
@ -57,7 +57,7 @@ var uri = loginRequest.ToUri();
|
|||||||
BrowserUtil.Open(uri);
|
BrowserUtil.Open(uri);
|
||||||
```
|
```
|
||||||
|
|
||||||
After the user logged in and consented your app, your `UWP` app will receive a callback:
|
After the user has logged in and consented your app, your `UWP` app will receive a callback:
|
||||||
|
|
||||||
```csharp
|
```csharp
|
||||||
protected override void OnActivated(IActivatedEventArgs args)
|
protected override void OnActivated(IActivatedEventArgs args)
|
||||||
@ -77,7 +77,7 @@ For a real example, have a look at the [Example.UWP](https://github.com/JohnnyCr
|
|||||||
|
|
||||||
# Using Spotify.Web.Auth
|
# Using Spotify.Web.Auth
|
||||||
|
|
||||||
For cross-platform CLI and desktop apps (non `UWP` apps), custom protocol handlers are sometimes not an option. The fallback here is a small cross-platform embedded web server running on `http://localhost:5000` serving javascript. The javscript will parse the fragment part of the URI and sends a request to the web server in the background. The web server then notifies your appliciation via event.
|
For cross-platform CLI and desktop apps (non `UWP` apps), custom protocol handlers are sometimes not an option. The fallback here is a small cross-platform embedded web server running on `http://localhost:5000` serving JavaScript. The JavaScript will parse the fragment part of the URI and sends a request to the web server in the background. The web server then notifies your appliciation via an event.
|
||||||
|
|
||||||
```csharp
|
```csharp
|
||||||
private static EmbedIOAuthServer _server;
|
private static EmbedIOAuthServer _server;
|
||||||
@ -101,7 +101,7 @@ private static async Task OnImplicitGrantReceived(object sender, ImplictGrantRes
|
|||||||
{
|
{
|
||||||
await _server.Stop();
|
await _server.Stop();
|
||||||
var spotify = new SpotifyClient(response.AccessToken);
|
var spotify = new SpotifyClient(response.AccessToken);
|
||||||
// do calls with spotify
|
// do calls with Spotify
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -3,7 +3,7 @@ id: iplayableitem
|
|||||||
title: IPlayableItem
|
title: IPlayableItem
|
||||||
---
|
---
|
||||||
|
|
||||||
When working with playlists or the current playing context, you will encounter a type `IPlayableItem`, which only contains a `Type` property. Spotify recently introduced shows/episodes to the API, and thus had to adapt API endpoints which previously just returned track objects. Now, playlists and the current playing context can include two types, tracks and episodes. To reflect this in our models, we introduced `IPlayableItem`.
|
When working with playlists or the current playing context, you will encounter the `IPlayableItem` type, which only contains a `Type` property. Spotify recently introduced shows/episodes to the API, and thus had to adapt API endpoints which previously just returned track objects. Now, playlists and the current playing context can include two types: tracks and episodes. To reflect this in our models, we introduced `IPlayableItem`.
|
||||||
|
|
||||||
```csharp
|
```csharp
|
||||||
var spotify = new SpotifyClient("YourAccessToken");
|
var spotify = new SpotifyClient("YourAccessToken");
|
||||||
@ -40,7 +40,7 @@ To this day, `IPlayableItem` can only be `FullTrack` or `FullEpisode`.
|
|||||||
|
|
||||||
## Fields
|
## Fields
|
||||||
|
|
||||||
When requesting just a subset of fields using the `fields` query parameter, the call might fail with an exception similar to `Received unkown playlist element type`. For example, the following call fails:
|
When requesting just a subset of fields using the `fields` query parameter, the call might fail with an exception similar to `Received unknown playlist element type`. For example, the following call fails:
|
||||||
|
|
||||||
```csharp
|
```csharp
|
||||||
var playlistGetItemsRequest = new PlaylistGetItemsRequest();
|
var playlistGetItemsRequest = new PlaylistGetItemsRequest();
|
||||||
|
@ -17,7 +17,7 @@ The `IHTTPLogger` interface can be found [here](https://github.com/JohnnyCrazy/S
|
|||||||
|
|
||||||
## SimpleConsoleHTTPLogger
|
## SimpleConsoleHTTPLogger
|
||||||
|
|
||||||
The library ships with a simple console-based logger
|
The library ships with a simple console-based logger.
|
||||||
|
|
||||||
```csharp
|
```csharp
|
||||||
var config = SpotifyClientConfig
|
var config = SpotifyClientConfig
|
||||||
|
@ -3,15 +3,15 @@ id: pagination
|
|||||||
title: Pagination
|
title: Pagination
|
||||||
---
|
---
|
||||||
|
|
||||||
When working with spotify responses, you will often encounter the `Paging<T>` type.
|
When working with Spotify responses, you will often encounter the `Paging<T>` type.
|
||||||
|
|
||||||
> The offset-based paging object is a container for a set of objects. It contains a key called items (whose value is an array of the requested objects) along with other keys like previous, next and limit that can be useful in future calls.
|
> The offset-based paging object is a container for a set of objects. It contains a key called Items (whose value is an array of the requested objects) along with other keys like Previous, Next and Limit which can be useful in future calls.
|
||||||
|
|
||||||
It allows to receive only a subset of all available data and dynamically check if more requests are required. The library supports `Paging<T>` responses in two ways:
|
It allows you to only receive a subset of all available data and dynamically check if more requests are required. The library supports `Paging<T>` responses in two ways:
|
||||||
|
|
||||||
## PaginateAll
|
## PaginateAll
|
||||||
|
|
||||||
`PaginateAll` will query all remaining elements based on a first page and return all of them in a `IList`. This method should not be used for a huge amount of pages (e.g `Search` Endpoint), since it stores every response in memory.
|
`PaginateAll` will query all remaining elements based on a first page and return all of them in an `IList`. This method should not be used for huge amounts of pages (e.g `Search` Endpoint), since it stores every response in memory.
|
||||||
|
|
||||||
```csharp
|
```csharp
|
||||||
// we need the first page
|
// we need the first page
|
||||||
@ -26,7 +26,7 @@ var allPages = await spotify.PaginateAll(page);
|
|||||||
:::info .NET Standard >= 2.1 required
|
:::info .NET Standard >= 2.1 required
|
||||||
:::
|
:::
|
||||||
|
|
||||||
`Paginate` is based on `IAsyncEnumerable` and streams pages instead of returning them all in one list. This allows to break the fetching early and keeps only 1 page in memory at a time. This method should always be preferred to `PaginateAll`
|
`Paginate` is based on `IAsyncEnumerable` and streams pages instead of returning them all in one list. This allows it to break the fetching early and keep only 1 page in memory at a time. This method should always be preferred to `PaginateAll`.
|
||||||
|
|
||||||
```csharp
|
```csharp
|
||||||
// we need the first page
|
// we need the first page
|
||||||
|
@ -3,11 +3,11 @@ id: pkce
|
|||||||
title: PKCE
|
title: PKCE
|
||||||
---
|
---
|
||||||
|
|
||||||
> The authorization code flow with PKCE is the best option for mobile and desktop applications where it is unsafe to store your client secret. It provides your app with an access token that can be refreshed. For further information about this flow, see IETF RFC-7636.
|
> The authorization code flow with PKCE is the best option for mobile and desktop applications where it is unsafe to store your client secret. It provides your app with an access token that can be refreshed. For further information about this flow, see [IETF RFC-7636](https://tools.ietf.org/html/rfc7636).
|
||||||
|
|
||||||
## Generating Challenge & Verifier
|
## Generating Challenge & Verifier
|
||||||
|
|
||||||
For every authentation request, a verify code and its challenge code needs to be generated. The class `PKCEUtil` can be used to generate those, either with random generated or self supplied values:
|
For every authentication request, a verify code and its challenge code needs to be generated. The class `PKCEUtil` can be used to generate those, either with random generated or self supplied values:
|
||||||
|
|
||||||
```csharp
|
```csharp
|
||||||
// Generates a secure random verifier of length 100 and its challenge
|
// Generates a secure random verifier of length 100 and its challenge
|
||||||
@ -22,7 +22,7 @@ var (verifier, challenge) = PKCEUtil.GenerateCodes("YourSecureRandomString");
|
|||||||
|
|
||||||
## Generating Login URI
|
## Generating Login URI
|
||||||
|
|
||||||
Like most auth flows, you'll need to redirect your user to spotify's servers so he is able to grant access to your application:
|
Like most auth flows, you'll need to redirect your user to Spotify's servers so they are able to grant access to your application:
|
||||||
|
|
||||||
```csharp
|
```csharp
|
||||||
// Make sure "http://localhost:5000/callback" is in your applications redirect URIs!
|
// Make sure "http://localhost:5000/callback" is in your applications redirect URIs!
|
||||||
@ -40,7 +40,7 @@ var uri = loginRequest.ToUri();
|
|||||||
// Redirect user to uri via your favorite web-server or open a local browser window
|
// Redirect user to uri via your favorite web-server or open a local browser window
|
||||||
```
|
```
|
||||||
|
|
||||||
When the user is redirected to the generated uri, he will have to login with his spotify account and confirm, that your application wants to access his user data. Once confirmed, he will be redirect to `http://localhost:5000/callback` and a `code` parameter is attached to the query. The redirect URI can also contain a custom protocol paired with UWP App Custom Protocol handler. This received `code` has to be exchanged for an `access_token` and `refresh_token`:
|
When the user is redirected to the generated uri, they will have to login with thei Spotify account and confirm that your application wants to access their user data. Once confirmed, they will be redirected to `http://localhost:5000/callback` and a `code` parameter is attached to the query. The redirect URI can also contain a custom protocol paired with UWP App Custom Protocol handler. This received `code` has to be exchanged for an `access_token` and `refresh_token`:
|
||||||
|
|
||||||
```csharp
|
```csharp
|
||||||
// This method should be called from your web-server when the user visits "http://localhost:5000/callback"
|
// This method should be called from your web-server when the user visits "http://localhost:5000/callback"
|
||||||
|
@ -3,7 +3,7 @@ id: retry_handling
|
|||||||
title: Retry Handling
|
title: Retry Handling
|
||||||
---
|
---
|
||||||
|
|
||||||
In [Error Handling](error_handling.md) we already found out that requests can fail. We provide a way to automatically retry requests via retry handlers. Note, by default no retries are performed.
|
In [Error Handling](error_handling.md), we already found out that requests can fail. We provide a way to automatically retry requests via retry handlers. Note that, by default, no retries are performed.
|
||||||
|
|
||||||
```csharp
|
```csharp
|
||||||
var config = SpotifyClientConfig
|
var config = SpotifyClientConfig
|
||||||
@ -18,12 +18,12 @@ public class YourCustomRetryHandler : IRetryHandler
|
|||||||
{
|
{
|
||||||
public Task<IResponse> HandleRetry(IRequest request, IResponse response, IRetryHandler.RetryFunc retry)
|
public Task<IResponse> HandleRetry(IRequest request, IResponse response, IRetryHandler.RetryFunc retry)
|
||||||
{
|
{
|
||||||
// request is the sent request and response the received response, obviously?
|
// request is the sent request and response is the received response, obviously
|
||||||
|
|
||||||
// don't retry:
|
// don't retry:
|
||||||
return response;
|
return response;
|
||||||
|
|
||||||
// retry once
|
// retry once:
|
||||||
var newResponse = retry(request);
|
var newResponse = retry(request);
|
||||||
return newResponse;
|
return newResponse;
|
||||||
|
|
||||||
@ -36,9 +36,9 @@ public class YourCustomRetryHandler : IRetryHandler
|
|||||||
|
|
||||||
A `SimpleRetryHandler` is included, which contains the following retry logic:
|
A `SimpleRetryHandler` is included, which contains the following retry logic:
|
||||||
|
|
||||||
* Retries the (configurable) status codes: 500, 502, 503 and 429
|
* Retries the (configurable) status codes: 500, 502, 503 and 429.
|
||||||
* `RetryAfter` - specifies the delay between retried calls
|
* `RetryAfter` - Specifies the delay between retried calls.
|
||||||
* `RetryTimes` - specifies the maxiumum amount of performed retries per call
|
* `RetryTimes` - Specifies the maxiumum amount of performed retries per call.
|
||||||
* `TooManyRequestsConsumesARetry` - Whether a failure of type "Too Many Requests" should use up one of the retry attempts.
|
* `TooManyRequestsConsumesARetry` - Whether a failure of type "Too Many Requests" should use up one of the retry attempts.
|
||||||
|
|
||||||
```csharp
|
```csharp
|
||||||
|
@ -3,13 +3,13 @@ id: token_swap
|
|||||||
title: Token Swap
|
title: Token Swap
|
||||||
---
|
---
|
||||||
|
|
||||||
Token Swap provides an authenticatiow flow where client-side apps (like cli/desktop/mobile apps) are still able to use long-living tokens and the oppurtunity to refresh them without exposing your application's secret. This however requires a server-side part to work.
|
Token Swap provides an authenticatiow flow where client-side apps (like CLI/desktop/mobile apps) are still able to use long-living tokens and the opportunity to refresh them without exposing your application's secret. This however requires a server-side part to work.
|
||||||
|
|
||||||
It is based on the [Authorization Code](authorization_code.md) flow and is also documented by spotify: [Token Swap and Refresh ](https://developer.spotify.com/documentation/ios/guides/token-swap-and-refresh/).
|
It is based on the [Authorization Code](authorization_code.md) flow and is also documented by Spotify: [Token Swap and Refresh ](https://developer.spotify.com/documentation/ios/guides/token-swap-and-refresh/).
|
||||||
|
|
||||||
## Flow
|
## Flow
|
||||||
|
|
||||||
The client uses the first part of the `Authorization Code` flow and redirects the user to spotify's login page. In this part, only the client id is required. Once the user logged in and confirmed the usage of your app, he will be redirect to a `http://localhost` server which grabs the `code` from the query parameters.
|
The client uses the first part of the `Authorization Code` flow and redirects the user to Spotify's login page. In this part, only the client id is required. Once the user logged in and confirmed the usage of your app, they will be redirect to a `http://localhost` server which grabs the `code` from the query parameters.
|
||||||
|
|
||||||
```csharp
|
```csharp
|
||||||
var request = new LoginRequest("http://localhost", "ClientId", LoginRequest.ResponseType.Code)
|
var request = new LoginRequest("http://localhost", "ClientId", LoginRequest.ResponseType.Code)
|
||||||
@ -46,7 +46,7 @@ var spotify = new SpotifyClient(newResponse.AccessToken);
|
|||||||
|
|
||||||
## Server Implementation
|
## Server Implementation
|
||||||
|
|
||||||
The server needs to support two endpoints, `/swap` and `/refresh` (endpoints can be named differently of course)
|
The server needs to support two endpoints, `/swap` and `/refresh` (endpoints can be named differently of course).
|
||||||
|
|
||||||
### Swap
|
### Swap
|
||||||
|
|
||||||
@ -58,7 +58,7 @@ curl -X POST "https://example.com/v1/swap"\
|
|||||||
--data "code=AQDy8...xMhKNA"
|
--data "code=AQDy8...xMhKNA"
|
||||||
```
|
```
|
||||||
|
|
||||||
The server needs to respond with content-type `application/json` and the at least the following body:
|
The server needs to respond with content-type `application/json` and the following body:
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
@ -78,7 +78,7 @@ curl -X POST "https://example.com/v1/refresh"\
|
|||||||
--data "refresh_token=NgCXRK...MzYjw"
|
--data "refresh_token=NgCXRK...MzYjw"
|
||||||
```
|
```
|
||||||
|
|
||||||
The server needs to respond with content-type `application/json` and the at least the following body:
|
The server needs to respond with content-type `application/json` and the following body:
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
@ -90,4 +90,4 @@ The server needs to respond with content-type `application/json` and the at leas
|
|||||||
|
|
||||||
## Example
|
## Example
|
||||||
|
|
||||||
An example server has been implemented in NodeJS with a .NET CLI client, located at [Example.TokenSwap](https://github.com/JohnnyCrazy/SpotifyAPI-NET/tree/master/SpotifyAPI.Web.Examples/Example.TokenSwap)
|
An example server has been implemented in Node.JS with a .NET CLI client, located at [Example.TokenSwap](https://github.com/JohnnyCrazy/SpotifyAPI-NET/tree/master/SpotifyAPI.Web.Examples/Example.TokenSwap).
|
||||||
|
@ -8,7 +8,7 @@ The modular structure of the library makes it easy to mock the API when unit tes
|
|||||||
```csharp
|
```csharp
|
||||||
public static async Task<bool> IsAdmin(IUserProfileClient userProfileClient)
|
public static async Task<bool> IsAdmin(IUserProfileClient userProfileClient)
|
||||||
{
|
{
|
||||||
// get loggedin user
|
// get logged in user
|
||||||
var user = await userProfileClient.Current();
|
var user = await userProfileClient.Current();
|
||||||
|
|
||||||
// only my user id is an admin
|
// only my user id is an admin
|
||||||
|
Loading…
Reference in New Issue
Block a user