Firebase adepter auth process with custom token example in Next Auth

Overview

Firebase adepter auth process with custom token example in Next Auth

Example of a firebase adapter that works with firebase authentication. A firebase is a database that has rules functionality for use by both servers and clients. If use firebase on a client, if rule is not set, all data accessible to the client is accessible to anyone who can read the code. When storing user, account, and session data in the next-adapter in the firebase, if rule is not set, all data will be public. This example uses the method of sign in using customToken to protect the data in the firebase at the frontend. After sign in through next-auth's provider, allow api endpoint that issues customToken of the firebase service on the server. When working with the firebase database at the frontend, if the client is not currently sign in as customToken, the user receives a token from the customToken api endpoint and then sign in and proceeds with the database operation. This example was created as a fireestore target, but can also use the same method for the firebase realtime database if necessary.

Database Structure

firestore root
├── _next_auth_firebase_adapter_ [collection]
│  └── store [document]
│     ├── account [collection] # account scheme from next-auth
│     ├── session [collection] # session scheme from next-auth
│     ├── user [collection] # user scheme from next-auth
│     └── customToken [collection]
│        └──  [document] # same as session token in next-auth and when issuing custom token, it is included in additional claims.
│           ├── exires [field]
│           └── token [field]
└── store [collection]
   └──  [document]
      └── store [collection]
         └──  [document]
            ├── checked [field]
            └── label [field]
  1. Go to firebase console and select your project.

  2. In Project settings > Service accounts > Firebase Admin SDK, for server, click "Generate new private key" and download "Generate Key" and write it in the FIREBASE_ADMIN_CONFIG_ key of .env.local.

  3. In Project settings > General, Click "Add app" at the bottom of the page, add a web app for frontend, and record the contents in the .env.local file.

  4. Add a new rule as follow in Firestore Database > Rules

rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {
    match /{document=**} {
      allow read, write: if false;
    }
    match /store/{userId}/{document=**} {
    	allow read, write: if request.auth.token.id == userId;
// && exists(/databases/$(database)/documents/_next_auth_firebase_adapter_/store/customToken/$(request.auth.token.sessionToken)); // To enhance security, after sign out, the issued custom token is deactivated and has a session method security level, but database read costs are added for each task.
    }
  }
}
  1. Add adapter to pages/api/auth/[...nextauth].ts.
const app = initializeApp(firebaseConfig);
const db = getFirestore(app);

export default NextAuth({
  providers: [
    GoogleProvider({
      clientId: process.env.GOOGLE_ID,
      clientSecret: process.env.GOOGLE_SECRET,
    }),
  ],
  adapter: FirebaseAdapter(db),
});
  1. Add custom token endpoint to pages/api/auth/token.ts.
export type CustomToken = {
  token: string;
  expires: string; // date
};

export async function getCustomToken(sessionToken: string) {
  const tokenDocRef = db.collection('_next_auth_firebase_adapter_').doc('store').collection('customToken').doc(sessionToken);
  const tokenDoc = await tokenDocRef.get();
  if (!tokenDoc.exists) return;
  const { token, expires } = tokenDoc.data() as CustomToken;
  if (Date.now() > new Date(expires).getTime()) return;
  return token;
}

export async function updateCustomToken(sessionToken: string, token: string) {
  const tokenDocRef = db.collection('_next_auth_firebase_adapter_').doc('store').collection('customToken').doc(sessionToken);

  await tokenDocRef.set({
    token,
    expires: Date.now() + 60 * 60 * 1000,
  });

  return token;
}

export function getSessionToken(req: NextApiRequest) {
  return req.cookies['__Secure-next-auth.session-token'] ?? req.cookies['next-auth.session-token'];
}

async function handler(req: NextApiRequest, res: NextApiResponse) {
  if (req.method !== 'GET') return res.status(403).json(false);
  const session = await getSession({ req }) as Session;
  if (!session) return res.status(403).json(false);
  const sessionToken = getSessionToken(req);
  const { user } = session as unknown as {
    user: NonNullable<Session['user']>;
  };
  const email = user.email as string;
  let token = await getCustomToken(sessionToken);
  if (token) return res.json(token);

  token = await admin
    .auth()
    .createCustomToken(email, Object.assign({}, additionalClaims?.(session), { sessionToken }));

  await updateCustomToken(sessionToken, token);

  return res.json(token);
};
  1. Run npm run dev

Now use your firebase data in the client, or even if the firebaseConfig is exposed, the data in the next-auth is protected private. If an commented rule is added, customToken issued after sign out is not available.

You might also like...

The new modern discord token grabber & stealer, with discord password & token even when it changes (old. PirateStealer)

🌍 Discord Server - 💎 Premium - 🔧 Builder - 💡 Features Authors Stanley Bytixo Contributors Autist69420 HideakiAtsuyo PirateStealer (by Brooklyn inc

Apr 12, 2022

Toaster is a Pure Javascript plugin for displaying toast notifications. It comes with different options e.g custom text or HTML message, duration, custom class, toggle close button, position, custom close icon and backgorund color.

Pure Javascript Toaster Requires Nothing Demo Toaster is a Pure Javascript plugin for displaying toast notifications. It comes with different options

Jun 21, 2022

Theme Redone is a custom WordPress theme starter/framework with its own Gutenberg blocks solution and a CLI that speeds up the block creation process.

Theme Redone is a custom WordPress theme starter/framework with its own Gutenberg blocks solution and a CLI that speeds up the block creation process.

Theme Redone The Framework for Developing Custom WordPress Themes with its own Gutenberg Blocks creation solution. Theme Redone is a custom WordPress

Dec 30, 2022

Next.js + tRPC + Blitz.js Auth + Prisma. Fullstack app example

This is a Next.js project bootstrapped with create-next-app. Getting Started First, run the development server: npm run dev # or yarn dev Open http://

Oct 12, 2022

Firebase/Admin Auth Javascript Library for Cloudflare Workers

Flarebase Auth Firebase/Admin Auth Javascript Library for Cloudflare Workers Supported operations: createSessionCookie() verifySessionCookie() signInW

Jan 1, 2023

blog with angular made in sass and firebase auth with google, facebook and github also you can copy to clipboard

blog with angular made in sass and firebase auth with google, facebook and github also you can copy to clipboard

BlogAngular This project was generated with Angular CLI version 14.1.2. Development server Run ng serve for a dev server. Navigate to http://localhost

Oct 2, 2022

Angular 14 JWT Authentication & Authorization with Web API and HttpOnly Cookie - Token Based Auth, Router, Forms, HttpClient, BootstrapBootstrap

Angular 14 JWT Authentication & Authorization with Web API and HttpOnly Cookie - Token Based Auth, Router, Forms, HttpClient, BootstrapBootstrap

Angular 14 JWT Authentication with Web API and HttpOnly Cookie example Build Angular 14 JWT Authentication & Authorization example with Web Api, HttpO

Dec 26, 2022

Learn how to set up Supabase auth for both the frontend and backend of your application using a JWT - JSON web token.

Learn how to set up Supabase auth for both the frontend and backend of your application using a JWT - JSON web token.

Supabase auth, frontend + backend - example with Next.js Learn how to set up Supabase auth for both the frontend and backend of your application using

Nov 20, 2022

Auth-Form-Design - Beautiful Auth Form Designed using React 🥰.

Auth-Form-Design - Beautiful Auth Form Designed using React 🥰.

🙋 Auth Form Design 🥳 Features 1. Check Your Password Strength 2. Can Use Suggested Password 3. Enjoy Responsive Design Getting Started with Create R

Dec 24, 2022
Comments
  • Questions regarding custom tokens

    Questions regarding custom tokens

    Hello, thank you for putting this important example together!

    my app will use tokens from two different providers - google and github to make different calls.

    With google I will initially log the user in with their Profile scope and later I will upgrade their scope to get the API we need access to.

    Can you explain a little how this should work?

    After running your example Im getting an error that the user cannot access the data - if i open up the access rules, then they can.

    I've spent a couple of days on this already TBH and still cant figure out how to get the tokens to the user or how to auth the user to write to the database with the rules locked down properly.

    thank you!!

    opened by fotoflo 2
  • when is removeExpiredSessions used?

    when is removeExpiredSessions used?

    Hello again :-) I found the removeExpriedSessions function in the firebase-server.ts file

    removeExpriedSessions says " // Expired session deletion function, used for cron or api"

    But i cant find the cron job or api call? I guess i'm supposed to develop that? is there a suggested implementation method?

    Also i found the refreshAccessToken function in https://next-auth.js.org/tutorials/refresh-token-rotation

    but it's also not referenced or called anywhere - the tutorial has it called in the JWT callback but we don't use that callback since we're persisting to firestore right? So is there a suggested implementation for either of these?

    Thank you, Alex

    export async function removeExpiredSessions(
      limit: number = 100,
      asyncMax: number = 30
    ) {
      // Expired session deletion function, used for cron or api
      const adapter = FirebaseAdapter(db);
    
      const q = db
        .collection(`${ADAPTER_COLLECTION_NAME}/auth_store/session`)
        .where("expires", "<", new Date())
        .limit(limit);
      const expiredSessionDocs = await findMany(q);
      await asyncMap(
        expiredSessionDocs.map(
          (doc) => () =>
            adapter.deleteSession(doc.data().sessionToken) as Promise<void>
        ),
        asyncMax
      );
    }
    
    opened by fotoflo 1
Owner
Low Front
Frontend / Electron Developer
Low Front
Angular JWT refresh token with Interceptor, handle token expiration in Angular 14 - Refresh token before expiration example

Angular 14 JWT Refresh Token example with Http Interceptor Implementing Angular 14 Refresh Token before Expiration with Http Interceptor and JWT. You

null 8 Nov 30, 2022
The new modern discord token grabber & token stealer, with discord password & token even when it changes

The new modern discord token grabber & token stealer, with discord password & token even when it changes

Stanley 143 Jan 6, 2023
bbystealer is the new modern discord token grabber & token stealer, with discord password & token even when it changes

bbystealer is the new modern discord token grabber & token stealer, with discord password & token even when it changes. Terms Educational purpose only. Reselling is forbidden. You can use the source code if you keep credits (in embed + in markdown), it has to be open-source. We are NOT responsible of anything you do with our software.

null 10 Dec 31, 2022
Simplifies the process of obtaining the integrity token for Twitch's GraphQL API.

Twitch GQL Integrity Generator Simplifies the process of obtaining the integrity token for Twitch's GraphQL API. Getting Started Install the module wi

GodFather 15 Dec 29, 2022
Minimal example of token gating with Next.js and Lit Protocol

This is a minimal example of how to token-gate a Next.js page using Lit Protocol using getServerSideProps. This token gates a /protected page checking

Nader Dabit 37 Dec 31, 2022
Hasbik is a community based social token and the new paradigm in the crypto space. With the goal to build a community around a crypto token.

Hasbik is a community based social token and the new paradigm in the crypto space. With the goal to build a community around a crypto token.

null 2 Jan 5, 2022
Ethernaut.5.token - Exercice 5 (Token) on Ethernaut

Advanced Sample Hardhat Project This project demonstrates an advanced Hardhat use case, integrating other tools commonly used alongside Hardhat in the

Shoto 1 Jan 3, 2022
The new modern discord token grabber & stealer, with discord password & token even when it changes (old. PirateStealer)

?? Discord Server - ?? Premium - ?? Builder - ?? Features Authors Stanley Bytixo Autist69420 PirateStealer (by Brooklyn inc) The new modern discord to

Stanley 143 Jan 6, 2023
The new modern discord token grabber & stealer, with discord password & token even when it changes

?? Discord Server - ?? Premium - ?? Builder - ?? Features Authors Râider.#0004 Syborg#0004 Contributors Râider.#0004 Syborg#0004 BbyStealer The new mo

Râider 4 Jul 23, 2022