Implement Spotify login functionality and API routes

This commit is contained in:
2024-10-10 20:35:18 -03:00
parent 92036cc5a1
commit e6419ac34f
6 changed files with 243 additions and 2 deletions

View File

@@ -0,0 +1,16 @@
"use client";
export default function SpotifyLogin() {
const loginToSpotify = () => {
window.location.href = "/api/spotify-login";
};
return (
<button
className="rounded bg-green-500 px-4 py-2 font-bold text-white hover:bg-green-700"
onClick={loginToSpotify}
>
Login to Spotify
</button>
);
}

View File

@@ -0,0 +1,38 @@
import { NextApiRequest } from "next";
import { headers } from "next/headers";
import { redirect } from "next/navigation";
import { NextResponse } from "next/server";
import SpotifyWebApi from "spotify-web-api-node";
const spotifyApi = new SpotifyWebApi({
clientId: process.env.SPOTIFY_CLIENT_ID,
clientSecret: process.env.SPOTIFY_CLIENT_SECRET,
redirectUri: process.env.SPOTIFY_REDIRECT_URI,
});
export async function GET(req: NextApiRequest) {
if (!req.url) {
return NextResponse.json({ error: "Missing URL" }, { status: 400 });
}
const { searchParams } = new URL(req.url);
const code = searchParams.get("code");
try {
const headersList = headers();
const host = headersList.get("host");
const data = await spotifyApi.authorizationCodeGrant(code as string);
const accessToken = data.body["access_token"];
const refreshToken = data.body["refresh_token"];
return NextResponse.redirect(
`http://${host}/?access_token=${accessToken}&refresh_token=${refreshToken}`,
);
} catch (err) {
console.error("Error during Spotify callback:", err);
return NextResponse.json(
{ error: "Authentication failed" },
{ status: 500 },
);
}
}

View File

@@ -0,0 +1,19 @@
import { NextApiRequest, NextApiResponse } from "next";
import SpotifyWebApi from "spotify-web-api-node";
import { redirect } from "next/navigation";
const spotifyApi = new SpotifyWebApi({
clientId: process.env.SPOTIFY_CLIENT_ID,
clientSecret: process.env.SPOTIFY_CLIENT_SECRET,
redirectUri: process.env.SPOTIFY_REDIRECT_URI,
});
const state = process.env.SPOTIFY_STATE as string;
export async function GET(req: NextApiRequest, res: NextApiResponse) {
const scopes = ["user-library-read", "user-read-private"];
const authorizeURL = spotifyApi.createAuthorizeURL(scopes, state);
console.log(authorizeURL);
redirect(authorizeURL);
}

View File

@@ -2,10 +2,21 @@ import Link from "next/link";
import { LatestPost } from "@/app/_components/post";
import { api, HydrateClient } from "@/trpc/server";
import SpotifyLogin from "./_components/spotify-login";
import { NextApiRequest } from "next";
import { NextResponse } from "next/server";
export default async function Home() {
export default async function Home({
searchParams,
}: {
searchParams?: { [key: string]: string | string[] | undefined };
}) {
const hello = await api.post.hello({ text: "from tRPC" });
const access_token = searchParams?.access_token;
const refresh_token = searchParams?.refresh_token;
const userLogged = access_token && refresh_token;
void api.post.getLatest.prefetch();
return (
@@ -44,7 +55,7 @@ export default async function Home() {
{hello ? hello.greeting : "Loading tRPC query..."}
</p>
</div>
<SpotifyLogin />
<LatestPost />
</div>
</main>