🕵️ SicherheitslückenHak5: Hackers Just Poisoned the Rust Supply Chain | Threat Wire(01.09.2026 um 14:00 Uhr)
🕵️ SicherheitslückenHak5: Hackers Found a Way Into Humanoid Robots | Threat Wire(04.09.2026 um 15:04 Uhr)
🔧 AI Nachrichten Bits und so #1021 (Passwort für Laufwerk)(31.08.2026 um 22:15 Uhr)
🔧 AI Nachrichten Bits und so #1022 (Wie Weißbier)(06.09.2026 um 20:39 Uhr)
🍏 iOS / Mac OSHue-App 6.0 ist da: das sind die Neuerungen(07.09.2026 um 17:21 Uhr)
🕵️ SicherheitslückenHak5: Hackers Just Poisoned the Rust Supply Chain | Threat Wire(01.09.2026 um 14:00 Uhr)
🕵️ SicherheitslückenHak5: Hackers Found a Way Into Humanoid Robots | Threat Wire(04.09.2026 um 15:04 Uhr)
🔧 AI Nachrichten Bits und so #1021 (Passwort für Laufwerk)(31.08.2026 um 22:15 Uhr)
🔧 AI Nachrichten Bits und so #1022 (Wie Weißbier)(06.09.2026 um 20:39 Uhr)
🍏 iOS / Mac OSHue-App 6.0 ist da: das sind die Neuerungen(07.09.2026 um 17:21 Uhr)

🔧 Programmierung 🕛 kürzlich 22 Min Lesezeit
0

NgSysV2-3.5: A Serious Svelte InfoSys: A Client-Server Version

↗ Quelle (dev.to)
🗣️ Stimme:
📑 Inhaltsübersicht

This post series is indexed at delivered some bad news - the Firestore auth object used client-side to supply information about a logged-in user isn't available server-side. This has the following consequences:




  • Server-side database code must use the Firestore Admin API. This is because Firestore Client API code that makes calls subject to database "rules" that reference auth fails when auth isn't available. By contrast, Admin API calls don't care about database rules. If you dropped the rules, client API calls would work server-side, but this would leave your database open to cyber attack (you've been working into your live Firestore database ever since you started using your local VSCode terminal - think about it).


  • Server-side code that uses data items such as userName and userEmail derived from auth must find another way of getting this information.




This post describes how you overcome these problems to produce a high-performance webapp that runs securely and efficiently server-side.






2. Authenticated Svelte server-side code in practice



If you've already got used to the Client call signatures, the requirement to switch to the Firestore Admin API is a nuisance. But you'll soon get used to this so it shouldn't hold you up significantly.



Getting user data, however, is a different matter. For many applications, access to user properties such as uId is critical to their design. For example, a webapp may need to ensure that users can only see their own data. Unfortunately, arranging this is quite a struggle. Here we go:




  1. First, on the client, you need to find a way to create an "idToken" package containing everything your server-side code might need to know about a user. Google provides a getIdToken() mechanism to construct this from the user's auth session data.

  2. Then you need to find a way of passing this package to the server. The mechanism used here registers this in a "header" that gets added to client calls to the server.

  3. Then you need to obtain a Google "Service Account" that enables you to authenticate your use of the Firestore Admin API on a Google server. The keys that define this need to be embedded securely in your project files (recall the firebaseConfig.env discussion in you should see the idToken displayed in an alert message.



    The Firebase ID token is a JSON Web Token (JWT). The JSON bit means that it is an object encoded as a character string using "Javascript Object Notation" (if this is your first sight of a "JSON" you might find it useful to ask chatGPT for background). JSONs are widely used where you need to pass Javascript objects around as character strings. The JWT JSON includes everything you might need to know about a user. I'll show you how you extract this information later in this post - it's not complicated.






    2.2 Passing the idToken to the server



    The mechanism described in this post sends the "IdToken" as a "cookie" in the "request header" that accompanies server requests. An "http header" is a packet of information that passes through the web when a client-based +page.svelte file sends a request to a server-based +page.server.js file. Such a request will be sent every time you read or write a Firestore document. A "cookie" is a string that gets added to every request header.



    This arrangement is complicated but is regarded as secure. From your point of view, as an IT student, it's also interesting and educational because it gives insight into web design internals.



    A client-side Javascript program could easily set a "regular" cookie containing the JWT but, for security reasons, you very much do not want to do this. If you can do this then anybody can. A server-side +page.server.js file, on the other hand, can set an "http-only" cookie in the client browser using a set-cookie call. Here's an example:




    CODE
        // Set a secure, HTTP-only cookie with the `idToken` token
    const headers = {
    'Set-Cookie': cookie.serialize('idToken', idToken, {
    httpOnly: true
    })
    };

    let response = new Response('Set cookie from server', {
    status: 200,
    headers,
    body: { message: 'Cookie set successfully' } // Optional message
    });

    return response;






    The httpOnly: true setting above means that, although the cookie is held client-side, it cannot be accessed from Javascript. In this way you can ensure that the value you set here is secure from tampering.



    The question you should be asking now is "How can a server-side +page.server.js file launch a Set-Cookie command to set an idToken when it doesn't know the idToken?".



    Welcome to the Svelte +server.js file. This is server-side code that can be called from client-side code with a Javascript fetch command. Such server-side code is called an "end-point". A fetch command is Javascript's native method for submitting a request to a web-based "end-point". The command enables you to include data in the request and so this is how you get an idToken value onto the server. Here's an example:




    CODE
    // client-side +page.svelte code
    const idToken = await user.getIdToken();

    // Send token to the server to set the cookie
    fetch("/api/login", {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({ idToken }),
    });






    and here's how the recipient +server.js file would retrieve this and extract its idToken.




    CODE
    // server-side +server.js code
    export async function POST({ request }) {
    const { idToken } = await request.json();
    }






    You are probably thinking "Why does this code use a "fetch" command to "send" something?" but there you are. "Fetch" was designed as a versatile API for making many different types of HTTP request. Ask chatGPT for a tutorial if you'd like to get some background. See .


  4. Navigate to IAM & Admin > Service Accounts and check that this points to your svelte-dev project (using the pulldown menu at the top left). The IAM (Identity and Access Management) screen lists all the Cloud permissions that control who can do what with the Google Cloud resources for your project. This deserves a 'post' in its own right, but this isn't the time

  5. Switch out of the IAM page and into the Service Accounts page by mousing over the toolbar at the left of the screen and clicking the one labelled "Service Accounts". You should see that a default account has already been created.

  6. Click the "+ Create Service Account" button at the top of the page and Create a new Service Account with a unique "Service account name such as "svelte-dev" (or whatever takes your fancy - it must be between 6 and 30 characters long and can only see lower-case alphanumerics and dashes). A version of this with a suffix guaranteed to be unique Cloud-wide is propagated into the "Service account ID" field. I suggest you accept whatever it offers.

  7. Now click the "Create And Continue" button and proceed to the "Grant this service account access to the project" section. Start by opening the pull-down menu on the field. This is a little complicated because it has two panels. The left-hand panel (which has a slider bar), allows you to select a product or service. The right-hand one lists the roles that are available for that service. Use the left-hand panel to select the "Firebase" Service and then select the "Admin SDK Administrator Service Agent" role from the right-hand panel. Click "Continue", then "Done" to return to the Service Accounts screen


  8. Finally, click the "three-dot" menu at the RHS of the entry for the "Firebase Admin SDK Service Agent" key that you've just created and select "manage keys". Click "Add Key" > Create new key > JSON > Create and note that a new file has appeared in your "downloads" folder. This is your "Service Account Key". All you have to do now is embed this in your project.







2.3.2 Embedding the downloaded Service Account in your project




  1. Create a /secrets folder in the root of your project to provide a secure location for the Service Account Key. Move the download Service Account file into a /secrets/serviceAccount.json file and add the "/secrets" folder and any editing history for it to your ".gitignore" file:




CODE
// .gitignore - fragment
# Secrets
/secrets/
/.history/secrets/






This is another instance of the safeguarding mechanism described previously in . It was used there to show how server-side code attempting to use the Firestore Client API would fail where the collections they were addressing were subject to Firestore database rules. This new version benefits from:




  • Service account keys that enable it to use Firestore Admin API commands and thus ignore the database rules

  • An idToken cookie that enables it to obtain details of an authenticated user




CODE
// src/routes/products-maintenance-sv/+page.server.js
import admin from 'firebase-admin';
import serviceAccount from '/secrets/service-account-file.json';
import cookie from 'cookie'; // install with "npm install cookie"
import { productNumberIsNumeric } from "$lib/utilities/productNumberIsNumeric";

// Give initialiseApp your project's Service Account Credentials. But make sure you only do this once.
// Things can get messy if you don't do this when your application is deployed in an environment where
// multiple instances of the server or multiple processes are running,
try {
if (!admin.apps.length) {
admin.initializeApp({
credential: admin.credential.cert(serviceAccount)
});
}
} catch (error) {
console.error("Failed to initialize Firebase Admin SDK:", error);
}

const adminDb = admin.firestore(); // Create an Admin SDK Firestore instance

export const actions = {
default: async ({ request }) => {

// Get the idToken from the request header
const cookies = cookie.parse(request.headers.get('cookie'));
const idToken = cookies.idToken;

// example of use of idToken to get the userEmail
const decodedToken = await admin.auth().verifyIdToken(idToken);
const userEmail = decodedToken.email;
console.log("userEmail from cookie : " + userEmail);

// capture of form data
const input = await request.formData();
const productNumber = input.get("productNumber");
const productDetails = input.get("productDetails");

// server-side repeat of client-side validation to catch hackers
const validationResult = productNumberIsNumeric(productNumber);

// Add the new record to the database
if (validationResult) {
try {
const productsDocData = { productNumber: parseInt(productNumber, 10), productDetails: productDetails };
const productsCollRef = adminDb.collection("products");
const productsDocRef = productsCollRef.doc(); // Creates a new doc with an auto-generated ID
await productsDocRef.set(productsDocData);

return { validationSuccess: true, databaseUpdateSuccess: true };

} catch (error) {
return { validationSuccess: true, databaseUpdateSuccess: false, databaseError: error.message };
}
} else {
return { validationSuccess: false, databaseUpdateSuccess: null };
}
}
};






Notice the curious way that the code builds the userEmail field




CODE
 // example of use of idToken to get the userEmail
const decodedToken = await admin.auth().verifyIdToken(idToken);
const userEmail = decodedToken.email;






The verifyIdToken method name might make you wonder whether this is trying to authenticate your user again. Don't worry - it's not. It's just doing a security check on the token's embedded "signatures" to assure itself that it hasn't been tampered with and hasn't expired.



The decodedToken created by verifyIdToken is a simple object containing email and userName properties etc for your authenticated user. The subsequent Firestore code doesn't use any of these, but I'm sure you can easily imagine how it might do so.



I suggest you use the "boiler-plate" approach again when coding Admin API calls - use chatGPT to convert the client code documented in

Vollständiger Original-Bericht
Ausführliche Details, Code-Beispiele & Hersteller-Stellungnahme auf dev.to.
↗ Original-Artikel auf dev.to lesen
Wie bewertest du diesen Beitrag?
1 Klick Feedback
Teilen mit Netzwerk & Team:

Community-Analysen & Experten-Meinungen 0

Verfasse deine eigene Analyse, teile Workarounds oder diskutiere diesen Vorfall im Blog.
Noch keine Community-Analyse verfasst. Markiere einen Textabschnitt oder klicke oben auf Eigene Analyse verfassen“!
Community Pulse: Relevanz-Einschätzung
1 Klick Experten-Votum
🔴 Akute Relevanz 0%
🟡 In Evaluierung 0%
🟢 Keine Auswirkung 0%
Spannende Innovation 0%
Verwandte Story-Cluster & Quellen (Vektor-KI)
Port 8095 Engine
1 Quelle
Hackers Just Poisoned the Rust Supply Chain | Threat Wire
1 Quelle
Hackers Found a Way Into Humanoid Robots | Threat Wire
1 Quelle
Bits und so #1021 (Passwort für Laufwerk)
Ähnliche Beiträge
🔍 Verwandte News

Auch interessante Nachrichten NgSysV2-3.5: A Serious Svelte InfoSys: A Client-Server Version

Thematisch verwandte Begriffe: NgSysV235, Serious, Svelte, InfoSys · 6 Treffer

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...