Series: Project Spotiviz
Tags: #nextjs #webdev #tutorial #security
👋 The "Why."
We all love Spotify Wrapped. It is a brilliant piece of product marketing that turns data into a cultural event. But as developers, waiting 12 months to see our listening habits feels like an eternity.
Why can't we see our data **now?
Welcome to Project Spotiviz. In this three-part series, we aren't just going to fetch a JSON file. We are going to engineer a production-ready, full-stack application that visualizes your music taste in real-time.
What we are building today:
We are ignoring the charts for a moment. Today, we focus on the gatekeeper: Authentication. 🔐
The Goal: By the end of this article, you will have a secure backend that can handshake with Spotify, exchange secret codes for access tokens, and store them in secure, HTTP-only cookies that client-side scripts can't touch.
🏛️ The Architecture
🛠️ The Stack
Framework: Next.js 14/15 (App Router)
Language: TypeScript
Styling: Tailwind CSS
State Management: Server-Side Cookies
Phase 1: The Spotify Developer Dashboard
.
Spotiviz Local).
# .env.local
SPOTIFY_CLIENT_ID=your_client_id_paste_here
SPOTIFY_CLIENT_SECRET=your_client_secret_paste_here
SPOTIFY_REDIRECT_URI=http://localhost:3000/api/callback
Phase 3: The Authorization URL 🔗
We need a button that kicks off the process. We need to construct a specific URL that tells Spotify exactly what permissions (Scopes) we want.
Create a utility library: lib/spotify.ts
const scopes = [
"user-read-recently-played",
"user-top-read",
"user-read-currently-playing",
"user-library-read"
].join(" ");
const params = {
scope: scopes,
response_type: "code",
redirect_uri: process.env.SPOTIFY_REDIRECT_URI!,
client_id: process.env.SPOTIFY_CLIENT_ID!,
};
const queryParamString = new URLSearchParams(params).toString();
export const LOGIN_URL = `https://accounts.spotify.com/authorize?${queryParamString}`;
Pro Tip: If you forget to ask for a specific scope here (like
user-top-read), the API will return a403 Forbiddenerror later when you try to fetch that data.
Phase 4: The "Handshake" (API Route) 🤝
Why did we use httpOnly: true?
If we stored the token in localStorage, a malicious chrome extension could steal the user's session. With HttpOnly cookies, the browser stores the cookie and attaches it to requests, but JavaScript cannot read it.
Why it's great: A comprehensive 1-hour walkthrough on building a REST API from scratch.
Fireship Video:
Why it's great: A full crash course on building a backend API using the popular MERN stack (MongoDB, Express, React, Node).
Hussein Nasser Video: gRPC Crash Course - Modes, Examples, Pros & Cons and more
Why it's great: An in-depth engineering look at gRPC, including its pros and cons compared to REST.
SOCIAL SHARE CARD GENERATOR