<linkrel="alternate"type="application/rss+xml"href="/SpotifyAPI-NET/news/rss.xml"title="SpotifyAPI-NET Blog RSS Feed">
<linkrel="alternate"type="application/atom+xml"href="/SpotifyAPI-NET/news/atom.xml"title="SpotifyAPI-NET Blog Atom Feed"><titledata-react-helmet="true">PKCE | SpotifyAPI-NET</title><metadata-react-helmet="true"property="og:url"content="https://johnnycrazy.github.io/SpotifyAPI-NET/docs/pkce"><metadata-react-helmet="true"name="docusaurus_locale"content="en"><metadata-react-helmet="true"name="docusaurus_version"content="current"><metadata-react-helmet="true"name="docusaurus_tag"content="docs-default-current"><metadata-react-helmet="true"property="og:title"content="PKCE | SpotifyAPI-NET"><metadata-react-helmet="true"name="description"content="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."><metadata-react-helmet="true"property="og:description"content="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."><linkdata-react-helmet="true"rel="shortcut icon"href="/SpotifyAPI-NET/img/favicon.ico"><linkdata-react-helmet="true"rel="canonical"href="https://johnnycrazy.github.io/SpotifyAPI-NET/docs/pkce"><linkdata-react-helmet="true"rel="alternate"href="https://johnnycrazy.github.io/SpotifyAPI-NET/docs/pkce"hreflang="en"><linkdata-react-helmet="true"rel="alternate"href="https://johnnycrazy.github.io/SpotifyAPI-NET/docs/pkce"hreflang="x-default"><linkrel="stylesheet"href="/SpotifyAPI-NET/assets/css/styles.fa980c59.css">
</span></div><divclass="token-line"style="color:#bfc7d5"><spanclass="token plain">// Generates a secure random verifier of length 120 and its challenge</span></div><divclass="token-line"style="color:#bfc7d5"><spanclass="token plain">var (verifier, challenge) = PKCEUtil.GenerateCodes(120);</span></div><divclass="token-line"style="color:#bfc7d5"><spanclass="token plain"style="display:inline-block">
</span></div><divclass="token-line"style="color:#bfc7d5"><spanclass="token plain">// Returns the passed string and its challenge (Make sure it's random and long enough)</span></div><divclass="token-line"style="color:#bfc7d5"><spanclass="token plain">var (verifier, challenge) = PKCEUtil.GenerateCodes("YourSecureRandomString");</span></div></div></div><buttontype="button"aria-label="Copy code to clipboard"class="copyButton_Ue-o">Copy</button></div></div><h2><aaria-hidden="true"tabindex="-1"class="anchor enhancedAnchor_2LWZ"id="generating-login-uri"></a>Generating Login URI<aclass="hash-link"href="#generating-login-uri"title="Direct link to heading">#</a></h2><p>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:</p><divclass="codeBlockContainer_K1bP"><divclass="codeBlockContent_hGly csharp"><divtabindex="0"class="prism-code language-csharp codeBlock_23N8 thin-scrollbar"><divclass="codeBlockLines_39YC"style="color:#bfc7d5;background-color:#292d3e"><divclass="token-line"style="color:#bfc7d5"><spanclass="token plain">// Make sure "http://localhost:5000/callback" is in your applications redirect URIs!</span></div><divclass="token-line"style="color:#bfc7d5"><spanclass="token plain">var loginRequest = new LoginRequest(</span></div><divclass="token-line"style="color:#bfc7d5"><spanclass="token plain"> new Uri("http://localhost:5000/callback"),</span></div><divclass="token-line"style="color:#bfc7d5"><spanclass="token plain">"YourClientId",</span></div><divclass="token-line"style="color:#bfc7d5"><spanclass="token plain"> LoginRequest.ResponseType.Code</span></div><divclass="token-line"style="color:#bfc7d5"><spanclass="token plain">)</span></div><divclass="token-line"style="color:#bfc7d5"><spanclass="token plain">{</span></div><divclass="token-line"style="color:#bfc7d5"><spanclass="token plain"> CodeChallengeMethod = "S256",</span></div><divclass="token-line"style="color:#bfc7d5"><spanclass="token plain"> CodeChallenge = challenge,</span></div><divclass="token-line"style="color:#bfc7d5"><spanclass="token plain"> Scope = new[] { Scopes.PlaylistReadPrivate, Scopes.PlaylistReadCollaborative }</span></div><divclass="token-line"style="color:#bfc7d5"><spanclass="token plain">};</span></div><divclass="token-line"style="color:#bfc7d5"><spanclass="token plain">var uri = loginRequest.ToUri();</span></div><divclass="token-line"style="color:#bfc7d5"><spanclass="token plain">// Redirect user to uri via your favorite web-server or open a local browser window</span></div></div></div><buttontype="button"aria-label="Copy code to clipboard"class="copyButton_Ue-o">Copy</button></div></div><p>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 <code>http://localhost:5000/callback</code> and a <code>code</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>code</code> has to be exchanged for an <code>access_token</code> and <code>refresh_token</code>:</p><divclass="codeBlockContainer_K1bP"><divclass="codeBlockContent_hGly csharp"><divtabindex="0"class="prism-code language-csharp codeBlock_23N8 thin-scrollbar"><divclass="codeBlockLines_39YC"style="color:#bfc7d5;background-color:#292d3e"><divclass="token-line"style="color:#bfc7d5"><spanclass="token plain">// This method should be called from your web-server when the user visits "http://localhost:5000/callback"</span></div><divclass="token-line"style="color:#bfc7d5"><spanclass="token plain">public Task GetCallback(string code)</span></div><divclass="token-line"style="color:#bfc7d5"><spanclass="token plain">{</span></div><divclass="token-line"style="color:#bfc7d5"><spanclass="token plain"> // Note that we u
</span></div><divclass="token-line"style="color:#bfc7d5"><spanclass="token plain"> var spotify = new SpotifyClient(initialResponse.AccessToken);</span></div><divclass="token-line"style="color:#bfc7d5"><spanclass="token plain"> // Also important for later: response.RefreshToken</span></div><divclass="token-line"style="color:#bfc7d5"><spanclass="token plain">}</span></div></div></div><buttontype="button"aria-label="Copy code to clipboard"class="copyButton_Ue-o">Copy</button></div></div><p>With PKCE you can also refresh tokens once they're expired:</p><divclass="codeBlockContainer_K1bP"><divclass="codeBlockContent_hGly csharp"><divtabindex="0"class="prism-code language-csharp codeBlock_23N8 thin-scrollbar"><divclass="codeBlockLines_39YC"style="color:#bfc7d5;background-color:#292d3e"><divclass="token-line"style="color:#bfc7d5"><spanclass="token plain">var newResponse = await new OAuthClient().RequestToken(</span></div><divclass="token-line"style="color:#bfc7d5"><spanclass="token plain"> new PKCETokenRefreshRequest("ClientId", initialResponse.RefreshToken)</span></div><divclass="token-line"style="color:#bfc7d5"><spanclass="token plain">);</span></div><divclass="token-line"style="color:#bfc7d5"><spanclass="token plain"style="display:inline-block">
</span></div><divclass="token-line"style="color:#bfc7d5"><spanclass="token plain">var spotify = new SpotifyClient(newResponse.AccessToken);</span></div></div></div><buttontype="button"aria-label="Copy code to clipboard"class="copyButton_Ue-o">Copy</button></div></div><p>If you do not want to take care of manually refreshing tokens, you can use <code>PKCEAuthenticator</code>:</p><divclass="codeBlockContainer_K1bP"><divclass="codeBlockContent_hGly csharp"><divtabindex="0"class="prism-code language-csharp codeBlock_23N8 thin-scrollbar"><divclass="codeBlockLines_39YC"style="color:#bfc7d5;background-color:#292d3e"><divclass="token-line"style="color:#bfc7d5"><spanclass="token plain">var authenticator = new PKCEAuthenticator(clientId, initialResponse);</span></div><divclass="token-line"style="color:#bfc7d5"><spanclass="token plain"style="display:inline-block">