colinhacks / next-firebase-ssr

An Next.js example repo for building authenticated pages with Firebase Authentication, cookies, and getServerSideProps
https://vriad.com/essays/nextjs-firebase-authentication
424 stars 61 forks source link

How do you secure an API route? #7

Open p45mark opened 3 years ago

p45mark commented 3 years ago

Thanks a lot for sharing this approach! I'm curious if you have any suggestions as to how I can secure an API route? I tried to just verify that the token exists and is valid, but calling this in my API returns the error that the token expired

From my secure page

export const getServerSideProps = async (ctx: GetServerSidePropsContext) => {
  try {
    const cookies = nookies.get(ctx);
    console.log(JSON.stringify(cookies, null, 2));
    const token = await firebaseAdmin.auth().verifyIdToken(cookies.token);
    const { uid, email } = token;

    // the user is authenticated!
    // FETCH STUFF HERE
    const data = await getDataFromAPI();

    return {
       props: data
    }

my API. This throws the error

export default async (
  { query: { id }, cookies }: NextApiRequest,
  res: NextApiResponse<Data>
) => {
  try {
    await firebaseAdmin.auth().verifyIdToken(cookies.token);
    const data = getDataHere();

    if (data) {
      res.statusCode = 200;
      res.setHeader('Content-Type', 'application/json');
      res.end(JSON.stringify(data));
    }
  } catch (error) {
    res.status(401).json({ message: 'Not Authorized!' });
  }
};
colinhacks commented 3 years ago

With API calls, the easiest and safest thing to do is generate an ID token (either grab it from the cookie client-side or generate a new one with firebaseClient.currentUser?.getIdToken() and send it as part of your request (either as a header or in the body of the request somewhere). Then validate it in the route logic with verifyIdToken like you described. This is safer than using cookies for CSRF reasons.

sandys commented 3 years ago

@colinhacks this was my question as well. is there any chance u can add a /api/ route to ur repo ?

I'm wondering if we have to take the code from here - https://github.com/vercel/next.js/tree/canary/examples/api-routes-apollo-server-and-client-auth