|
| 1 | +export async function redirectToAuthCodeFlow(clientId: string) { |
| 2 | + const verifier = generateCodeVerifier(128); |
| 3 | + const challenge = await generateCodeChallenge(verifier); |
| 4 | + |
| 5 | + localStorage.setItem("verifier", verifier); |
| 6 | + |
| 7 | + const params = new URLSearchParams(); |
| 8 | + params.append("client_id", clientId); |
| 9 | + params.append("response_type", "code"); |
| 10 | + params.append("redirect_uri", "http://localhost:5173/callback"); |
| 11 | + params.append("scope", "user-read-private user-read-email"); |
| 12 | + params.append("code_challenge_method", "S256"); |
| 13 | + params.append("code_challenge", challenge); |
| 14 | + |
| 15 | + document.location = `https://accounts.spotify.com/authorize?${params.toString()}`; |
| 16 | +} |
| 17 | + |
| 18 | +export async function getAccessToken(clientId: string, code: string) { |
| 19 | + const verifier = localStorage.getItem("verifier"); |
| 20 | + |
| 21 | + const params = new URLSearchParams(); |
| 22 | + params.append("client_id", clientId); |
| 23 | + params.append("grant_type", "authorization_code"); |
| 24 | + params.append("code", code); |
| 25 | + params.append("redirect_uri", "http://localhost:5173/callback"); |
| 26 | + params.append("code_verifier", verifier!); |
| 27 | + |
| 28 | + const result = await fetch("https://accounts.spotify.com/api/token", { |
| 29 | + method: "POST", |
| 30 | + headers: { "Content-Type": "application/x-www-form-urlencoded" }, |
| 31 | + body: params |
| 32 | + }); |
| 33 | + |
| 34 | + const { access_token } = await result.json(); |
| 35 | + return access_token; |
| 36 | +} |
| 37 | + |
| 38 | +function generateCodeVerifier(length: number) { |
| 39 | + let text = ''; |
| 40 | + let possible = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'; |
| 41 | + |
| 42 | + for (let i = 0; i < length; i++) { |
| 43 | + text += possible.charAt(Math.floor(Math.random() * possible.length)); |
| 44 | + } |
| 45 | + return text; |
| 46 | +} |
| 47 | + |
| 48 | +async function generateCodeChallenge(codeVerifier: string) { |
| 49 | + const data = new TextEncoder().encode(codeVerifier); |
| 50 | + const digest = await window.crypto.subtle.digest('SHA-256', data); |
| 51 | + return btoa(String.fromCharCode.apply(null, [...new Uint8Array(digest)])) |
| 52 | + .replace(/\+/g, '-') |
| 53 | + .replace(/\//g, '_') |
| 54 | + .replace(/=+$/, ''); |
| 55 | +} |
0 commit comments