#route handler call on client side

1 messages · Page 1 of 1 (latest)

calm raptor
#

i created my api route to return me guild objects from discord

import { PartialGuild } from "@/app/types"
import { NextApiRequest } from "next"
import { getToken } from "next-auth/jwt"
import { NextResponse } from "next/server"

async function getGuilds(token: string): Promise<PartialGuild[]> {
  const res = await fetch("https://discord.com/api/users/@me/guilds", {
    headers: {
      Authorization: token,
    },
  })
  return await res.json()
}

export async function GET(req: NextApiRequest) {
  const token = await getToken({ req })
  if (!token?.accessToken) {
    return NextResponse.json({ error: "Unauthorized" }, { status: 401 })
  }
  const userGuilds = await getGuilds(`Bearer ${token.accessToken}`)
  const botGuilds = await getGuilds(`Bot ${process.env.DISCORD_BOT_TOKEN}`)

  const adminUserGuilds = userGuilds.filter(
    ({ permissions }) => (parseInt(permissions) & 0x8) === 0x8
  )

  const mutualGuilds = adminUserGuilds.filter((guild) =>
    botGuilds.some((botGuild) => botGuild.id === guild.id)
  )
  return NextResponse.json({ adminUserGuilds, mutualGuilds })
}

``` code for it ^

and it works, but only when i query it manually by typing the api link to browser, now how can i get that data in component cause using this code ```tsx
export default async function Dashboard() {
  const res = await fetch("http://localhost:3000/api/user/getMutualGuilds")
  const servers = await res.json()
  console.log(servers)

  return (
    <div>
      <h1>{JSON.stringify(servers, null, 2)}</h1>
    </div>
  )
}

``` returns `{ "error": "Unauthorized" }`
grand bridgeBOT
#

Hi @calm raptor. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave:

#

The error message { "error": "Unauthorized" } is returned because the accessToken is not found in the GET function of your API route. This accessToken is retrieved using the getToken function from next-auth/jwt, which requires a valid session to be established.

When you're making a request from the browser directly, it's likely that a valid session exists (you're probably logged in), so the accessToken can be retrieved and the API route works as expected.

However, when you're making a request from within your Dashboard component using fetch, the request does not automatically include credentials such as cookies which are needed for next-auth to validate the session and provide the accessToken.

To include credentials in your fetch request, you can add the credentials: 'include' option:

export default async function Dashboard() {
  const res = await fetch("<http://localhost:3000/api/user/getMutualGuilds",> {
    credentials: 'include',
  })
  const servers = await res.json()
  console.log(servers)

  return (
    <div>
      <h1>{JSON.stringify(servers, null, 2)}</h1>
    </div>
  )
}

This tells the browser to include credentials (like cookies) with the fetch request, which should allow next-auth to validate the session and provide the accessToken.

Please note that this solution assumes that you have a valid session when rendering the Dashboard component. If you're not logged in, you'll need to ensure that the user is authenticated before trying to fetch data from this API route.

For more information on data fetching in Next.js, you can refer to the official documentation (https://nextjs.org/docs/app/building-your-application/data-fetching).

Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:

#

@earnest pond kapa.ai is still learning and improving, please let us know how it did by reacting below

calm raptor
#

@grand bridge its still Unauthorized

grand bridgeBOT
#

Let me check the knowledge base for you. One moment! :books:

#

The issue you're facing is likely due to the fact that Next.js API routes do not have access to the cookies from the browser by default. This is why the getToken function is unable to retrieve the token, resulting in the "Unauthorized" error.

To solve this, you need to make sure that the session is being passed to the API route. This can be done by using the getSession function from next-auth/client in your component and passing the session to your API route.

Here's how you can modify your Dashboard component:

import { getSession } from 'next-auth/client'

export default async function Dashboard() {
  const session = await getSession();
  const res = await fetch("<http://localhost:3000/api/user/getMutualGuilds",> {
    method: 'GET',
    headers: {
      'Content-Type': 'application/json',
      'Authorization': `Bearer ${session.accessToken}`
    },
  })
  const servers = await res.json()
  console.log(servers)

  return (
    <div>
      <h1>{JSON.stringify(servers, null, 2)}</h1>
    </div>
  )
}

In this code, we're using getSession to get the current session, and then we're passing the accessToken from the session in the Authorization header of our fetch request.

Please note that this solution assumes that you're using NextAuth for authentication and that the session object contains an accessToken. If your setup is different, you might need to adjust the code accordingly.

For more information on NextAuth sessions, you can refer to the official documentation (https://next-auth.js.org/getting-started/client).

Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: