Home > Blockchain >  How do you pass authentication from an RTK Query to firebase functions to access realtime database?
How do you pass authentication from an RTK Query to firebase functions to access realtime database?

Time:12-04

In the frontend, everything is authenticated properly using the firebase signin api, and a listener for auth changes to get the token and User info to pass to the backend.

this is the general fields used in RTK Query:

  reducerPath: "api",
  baseQuery: fetchBaseQuery({
    baseUrl: "https://us-central1.cloudfunctions.net/api",
    mode: "cors",
    prepareHeaders: (headers) => {
      headers.set("Access-Control-Allow-Methods", "GET,PUT,POST,DELETE");
      headers.set("Access-Control-Allow-Origin", "*");
      headers.set("Access-Control-Allow-Headers", "Content-Type");
      const authToken = localStorage.getItem("AuthToken");
      if (authToken) headers.set("authorization", authToken);
      return headers;
    },
  }),
  endpoints: (builder) => ({
    getWorkouts: builder.query<GetWorkoutList, string>({
      query: (userId) => ({
        url: `/workouts/${userId}`,
      }),
    }),
---rest of endpoints---

and this it is checking for successful frontend authentication changes:


  useEffect(() => {
    const unsubscribe = onAuthStateChanged(auth, async (userInfo) => {
      setUser(userInfo);
      if (userInfo === null) {
        localStorage.clear();
      } else {
        const token = await userInfo.getIdToken(true);
        localStorage.setItem("AuthToken", `Bearer ${token}`);
      }
    });
    return unsubscribe;
  }, [user]);

In firebase functions, it is using admin levels to verify the token from the frontend and the rest of the backend is using regular user permissions.

const decodedIdToken = await adminApp.auth().verifyIdToken(idToken);

The problem is that using the admin level bypasses the security rules and doesn't actually provide the authentication for a user to reach the database.

What is the actual step that is missing to give the request to the realtime database the authentication object for firebase rules to be successfully passed.

    "users":{
      "$userId":{
        ".write": "$userId == auth.uid",
        ".read": "$userId == auth.uid",
      },
    },

(auth == null)

CodePudding user response:

Requests from the Admin SDK are normally fully trusted and bypass the security rules.

For the Realtime Database though you can pass a databaseAuthVariableOverride when initializing the Admin SDK, and pass your own UID as shown in the documentation on authenticating with limited privileges. Although I've never tested this myself, I think you might be able to pass other claims too - as the information you pass just becomes the auth variable in the rules.

  • Related