Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Select an option

  • Save Uvacoder/674d9e157b7ba7dbcbf21ad7af5f3dfb to your computer and use it in GitHub Desktop.

Select an option

Save Uvacoder/674d9e157b7ba7dbcbf21ad7af5f3dfb to your computer and use it in GitHub Desktop.
import React, { useState, useEffect } from "react";
const clientId = "b841fe980d704720934f655f5e92d2e3";
const redirectUrl = "http://localhost:3000/callback";
const authorizationEndpoint = "https://accounts.spotify.com/authorize";
const tokenEndpoint = "https://accounts.spotify.com/api/token";
const scope =
"user-read-private user-read-email playlist-read-private playlist-modify-private user-library-read user-library-modify";
function SpotifyLogin() {
const [currentToken, setCurrentToken] = useState({
access_token: localStorage.getItem("access_token") || null,
refresh_token: localStorage.getItem("refresh_token") || null,
expires_in: localStorage.getItem("expires_in") || null,
expires: localStorage.getItem("expires") || null,
});
const generateRandomString = () => {
const possible =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
const randomValues = crypto.getRandomValues(new Uint8Array(64));
const randomValue = randomValues.reduce(
(acc, x) => acc + possible[x % possible.length],
""
);
return randomValue;
};
const generateCodeChallenge = async (codeVerifier) => {
const hashed = await crypto.subtle.digest(
"SHA-256",
new TextEncoder().encode(codeVerifier)
);
return btoa(String.fromCharCode(...new Uint8Array(hashed)))
.replace(/=/g, "")
.replace(/\+/g, "-")
.replace(/\//g, "_");
};
const redirectToSpotifyAuthorize = async () => {
const codeVerifier = generateRandomString();
localStorage.setItem("code_verifier", codeVerifier);
alert(codeVerifier);
const codeChallenge = await generateCodeChallenge(codeVerifier);
console.log(codeChallenge);
const authUrl = new URL(authorizationEndpoint);
authUrl.search = new URLSearchParams({
response_type: "code",
client_id: clientId,
scope: scope,
code_challenge_method: "S256",
code_challenge: codeChallenge,
redirect_uri: redirectUrl,
}).toString();
console.log(authUrl);
return authUrl;
// ?response_type=code&client_id=b841fe980d704720934f655f5e92d2e3&scope=user-read-private+user-read-email+playlist-read-private+playlist-modify-private+user-library-read+user-library-modify&code_challenge_method=S256&code_challenge=0QxO8vQzlcAOCmPOBSbXxLt_EqkUxJ52p-OsDq4DjTY&redirect_uri=http%3A%2F%2Flocalhost%3A3000%2Fcallback
// Redirect the user to the Spotify authorization page
window.location.href = authUrl.toString();
// Log the authorization code when the user is redirected back to your application
const handleRedirect = () => {
const params = new URLSearchParams(window.location.search);
const code = params.get("code");
console.log(params, code);
if (code) {
console.log("Authorization Code:", code);
}
};
// Attach the handleRedirect function to window's onload event to execute it when the page loads after redirection
window.onload = handleRedirect;
};
const getToken = async (code) => {
const codeVerifier = localStorage.getItem("code_verifier");
const response = await fetch(tokenEndpoint, {
method: "POST",
headers: {
"Content-Type": "application/x-www-form-urlencoded",
},
body: new URLSearchParams({
client_id: clientId,
grant_type: "authorization_code",
code: code,
redirect_uri: redirectUrl,
code_verifier: codeVerifier,
}),
});
return response.json();
};
const saveToken = (token) => {
localStorage.setItem("access_token", token.access_token);
localStorage.setItem("refresh_token", token.refresh_token);
localStorage.setItem("expires_in", token.expires_in);
const now = new Date();
const expiry = new Date(now.getTime() + token.expires_in * 1000);
localStorage.setItem("expires", expiry);
setCurrentToken(token);
};
useEffect(() => {
const fetchData = async () => {
const code = new URLSearchParams(window.location.search).get("code");
if (code) {
const token = await getToken(code);
saveToken(token);
window.history.replaceState(
{},
document.title,
window.location.pathname
); // Remove code from URL
}
};
fetchData();
}, []);
// useEffect(() => {
// if (currentToken.access_token) {
// getUserData().then((userData) => {
// // Render logged-in template with user data
// console.log("User Data:", userData);
// });
// }
// }, [currentToken.access_token]);
const refreshToken = async () => {
const response = await fetch(tokenEndpoint, {
method: "POST",
headers: {
"Content-Type": "application/x-www-form-urlencoded",
},
body: new URLSearchParams({
client_id: clientId,
grant_type: "refresh_token",
refresh_token: currentToken.refresh_token,
}),
});
return response.json();
};
const getUserData = async () => {
const response = await fetch("https://api.spotify.com/v1/me", {
method: "GET",
headers: { Authorization: "Bearer " + currentToken.access_token },
});
return response.json();
};
const logoutClick = () => {
localStorage.clear();
window.location.href = redirectUrl;
};
const refreshTokenClick = async () => {
const token = await refreshToken();
saveToken(token);
};
return (
<div>
{currentToken.access_token ? (
<div>
<h1>User is logged in</h1>
<button onClick={logoutClick}>Logout</button>
<button onClick={refreshTokenClick}>Refresh Token</button>
</div>
) : (
<div>
<h1>User is not logged in</h1>
<button onClick={redirectToSpotifyAuthorize}>
Login with Spotify
</button>
</div>
)}
</div>
);
}
export default SpotifyLogin;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment