Salta al contenuto
0
  • Home
  • Piero Bosio
  • Blog
  • Mondo
  • Fediverso
  • News
  • Categorie
  • Recenti
  • Popolare
  • Tag
  • Utenti
  • Home
  • Piero Bosio
  • Blog
  • Mondo
  • Fediverso
  • News
  • Categorie
  • Recenti
  • Popolare
  • Tag
  • Utenti
Skin
  • Light
  • Brite
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Predefinito (Nessuna skin)
  • Nessuna skin
Collassa

Piero Bosio Web Site

Forum federato con il resto del mondo. Non contano le istanze, contano le persone

  1. Home
  2. Categorie
  3. Senza categoria
  4. Unable to Retrieve CSRF Token via /api/config Using express.sid After Keycloak Login

Unable to Retrieve CSRF Token via /api/config Using express.sid After Keycloak Login

Pianificato Fissato Bloccato Spostato Senza categoria
4 Post 3 Autori 1 Visualizzazioni
  • Da Vecchi a Nuovi
  • Da Nuovi a Vecchi
  • Più Voti
Rispondi
  • Topic risposta
Effettua l'accesso per rispondere
Questa discussione è stata eliminata. Solo gli utenti con diritti di gestione possono vederla.
  • baluundefined Questo utente è esterno a questo forum
    baluundefined Questo utente è esterno a questo forum
    balu
    scritto su ultima modifica di
    #1

    Hi,
    I have a question regarding the express.sid cookie:

    After login, the express.sid is generated and stored in the cookies.

    I tried using this session ID to fetch the CSRF token by calling /api/config, but it doesn’t seem to work for me.

    My goal is:

    Successfully retrieve a valid CSRF token.

    Use it to create topics or posts via the Write API.

    Ensure that once I have this token and session, I can access all the required NodeBB APIs.

    Could you please clarify the correct approach to:

    Retrieve and use the CSRF token with the express.sid?

    Authenticate API requests (like creating topics or posts) when using Keycloak for login instead of NodeBB’s built-in login?

    Any guidance or best practices for this integration would be greatly appreciated.

    app.post('/api/login', async (req, res) => {
    try {
    const { username, password } = req.body || {}
    if (!username || !password) {
    return res.status(400).json({ error: 'Missing username or password' })
    }
    // 1) Login against Keycloak (Direct Access Grant)
    const tokenResponse = await fetchKeycloakTokens({ username, password });

    // 2) Get user profile to build NodeBB payload
    const userinfo = await fetchUserInfo({ accessToken: tokenResponse.access_token });
    
    // 3) Build session-sharing JWT for NodeBB
    // Minimal fields: id (unique), username, email
    const nodebbPayload = {
        id: userinfo.sub || userinfo.preferred_username || username,
        username: userinfo.preferred_username || username,
        email: userinfo.email || undefined,
        fullname: userinfo.name || undefined,
    };
    if (!SESSION_SHARING_JWT_SECRET) {
        return res.status(500).json({ error: 'Server not configured: SESSION_SHARING_JWT_SECRET missing' });
    }
    const signed = await jwt.sign(nodebbPayload, SESSION_SHARING_JWT_SECRET, { expiresIn: '1h' });
    
     const loginRes = await axios.post('http://localhost:4567/api/v3/utilities/login', {
        username,
        password
    }, {
        headers: {
            "Content-Type": "application/json",
            "Authorization": `Bearer ${signed}`, // pass your Bearer token here
        },
        withCredentials: true
    });
    
    console.log(loginRes, "LOGIN RESPONSE");
    // 4) Set cookie for NodeBB domain so it can pick it up
    const response = await axios.get('http://192.168.60.108:4567/api/config', { withCredentials: true });
    const newToken = response?.data?.csrf_token;
    
    const cookieOptions = {
        httpOnly: true,
        secure: false,
        sameSite: 'none',
        path: '/',
        maxAge: 8 * 60 * 60 * 10000,
        domain: '192.168.60.108'
    }
    
    res.cookie("token", signed, cookieOptions);
    res.cookie('csrf_token', newToken, cookieOptions);
    
    return res.json({ success: true, message: "login successfully", redirect: NODEBB_BASE_URL, keycloakAccessToken: tokenResponse.access_token });
    

    } catch (err) {
    // eslint-disable-next-line no-console
    console.error('Login error:', err?.response?.data || err?.message || err);
    const status = err?.response?.status || 500
    const message = err?.response?.data?.error_description || err?.response?.data?.error || err?.message || 'Unexpected error';
    return res.status(status).json({ success: false, error: message });
    }

    });
    In the /api/login API, I called the /api/config API, but when I check the /api/config API in Postman using the express.sid generated after login, it never returns the response for that specific user.

    Thanks in advance!

    HenryCharlesundefined baluundefined 2 Risposte Ultima Risposta
    • baluundefined balu

      Hi,
      I have a question regarding the express.sid cookie:

      After login, the express.sid is generated and stored in the cookies.

      I tried using this session ID to fetch the CSRF token by calling /api/config, but it doesn’t seem to work for me.

      My goal is:

      Successfully retrieve a valid CSRF token.

      Use it to create topics or posts via the Write API.

      Ensure that once I have this token and session, I can access all the required NodeBB APIs.

      Could you please clarify the correct approach to:

      Retrieve and use the CSRF token with the express.sid?

      Authenticate API requests (like creating topics or posts) when using Keycloak for login instead of NodeBB’s built-in login?

      Any guidance or best practices for this integration would be greatly appreciated.

      app.post('/api/login', async (req, res) => {
      try {
      const { username, password } = req.body || {}
      if (!username || !password) {
      return res.status(400).json({ error: 'Missing username or password' })
      }
      // 1) Login against Keycloak (Direct Access Grant)
      const tokenResponse = await fetchKeycloakTokens({ username, password });

      // 2) Get user profile to build NodeBB payload
      const userinfo = await fetchUserInfo({ accessToken: tokenResponse.access_token });
      
      // 3) Build session-sharing JWT for NodeBB
      // Minimal fields: id (unique), username, email
      const nodebbPayload = {
          id: userinfo.sub || userinfo.preferred_username || username,
          username: userinfo.preferred_username || username,
          email: userinfo.email || undefined,
          fullname: userinfo.name || undefined,
      };
      if (!SESSION_SHARING_JWT_SECRET) {
          return res.status(500).json({ error: 'Server not configured: SESSION_SHARING_JWT_SECRET missing' });
      }
      const signed = await jwt.sign(nodebbPayload, SESSION_SHARING_JWT_SECRET, { expiresIn: '1h' });
      
       const loginRes = await axios.post('http://localhost:4567/api/v3/utilities/login', {
          username,
          password
      }, {
          headers: {
              "Content-Type": "application/json",
              "Authorization": `Bearer ${signed}`, // pass your Bearer token here
          },
          withCredentials: true
      });
      
      console.log(loginRes, "LOGIN RESPONSE");
      // 4) Set cookie for NodeBB domain so it can pick it up
      const response = await axios.get('http://192.168.60.108:4567/api/config', { withCredentials: true });
      const newToken = response?.data?.csrf_token;
      
      const cookieOptions = {
          httpOnly: true,
          secure: false,
          sameSite: 'none',
          path: '/',
          maxAge: 8 * 60 * 60 * 10000,
          domain: '192.168.60.108'
      }
      
      res.cookie("token", signed, cookieOptions);
      res.cookie('csrf_token', newToken, cookieOptions);
      
      return res.json({ success: true, message: "login successfully", redirect: NODEBB_BASE_URL, keycloakAccessToken: tokenResponse.access_token });
      

      } catch (err) {
      // eslint-disable-next-line no-console
      console.error('Login error:', err?.response?.data || err?.message || err);
      const status = err?.response?.status || 500
      const message = err?.response?.data?.error_description || err?.response?.data?.error || err?.message || 'Unexpected error';
      return res.status(status).json({ success: false, error: message });
      }

      });
      In the /api/login API, I called the /api/config API, but when I check the /api/config API in Postman using the express.sid generated after login, it never returns the response for that specific user.

      Thanks in advance!

      HenryCharlesundefined Questo utente è esterno a questo forum
      HenryCharlesundefined Questo utente è esterno a questo forum
      HenryCharles
      scritto su ultima modifica di
      #2

      You’ll need both the session cookie and its matching CSRF token. Log in so NodeBB sets the cookie, then call /api/config with it to get the token. With Keycloak, it’s best to use the session-sharing plugin and JWT so NodeBB handles sessions and CSRF for you.

      1 Risposta Ultima Risposta
      • baluundefined balu

        Hi,
        I have a question regarding the express.sid cookie:

        After login, the express.sid is generated and stored in the cookies.

        I tried using this session ID to fetch the CSRF token by calling /api/config, but it doesn’t seem to work for me.

        My goal is:

        Successfully retrieve a valid CSRF token.

        Use it to create topics or posts via the Write API.

        Ensure that once I have this token and session, I can access all the required NodeBB APIs.

        Could you please clarify the correct approach to:

        Retrieve and use the CSRF token with the express.sid?

        Authenticate API requests (like creating topics or posts) when using Keycloak for login instead of NodeBB’s built-in login?

        Any guidance or best practices for this integration would be greatly appreciated.

        app.post('/api/login', async (req, res) => {
        try {
        const { username, password } = req.body || {}
        if (!username || !password) {
        return res.status(400).json({ error: 'Missing username or password' })
        }
        // 1) Login against Keycloak (Direct Access Grant)
        const tokenResponse = await fetchKeycloakTokens({ username, password });

        // 2) Get user profile to build NodeBB payload
        const userinfo = await fetchUserInfo({ accessToken: tokenResponse.access_token });
        
        // 3) Build session-sharing JWT for NodeBB
        // Minimal fields: id (unique), username, email
        const nodebbPayload = {
            id: userinfo.sub || userinfo.preferred_username || username,
            username: userinfo.preferred_username || username,
            email: userinfo.email || undefined,
            fullname: userinfo.name || undefined,
        };
        if (!SESSION_SHARING_JWT_SECRET) {
            return res.status(500).json({ error: 'Server not configured: SESSION_SHARING_JWT_SECRET missing' });
        }
        const signed = await jwt.sign(nodebbPayload, SESSION_SHARING_JWT_SECRET, { expiresIn: '1h' });
        
         const loginRes = await axios.post('http://localhost:4567/api/v3/utilities/login', {
            username,
            password
        }, {
            headers: {
                "Content-Type": "application/json",
                "Authorization": `Bearer ${signed}`, // pass your Bearer token here
            },
            withCredentials: true
        });
        
        console.log(loginRes, "LOGIN RESPONSE");
        // 4) Set cookie for NodeBB domain so it can pick it up
        const response = await axios.get('http://192.168.60.108:4567/api/config', { withCredentials: true });
        const newToken = response?.data?.csrf_token;
        
        const cookieOptions = {
            httpOnly: true,
            secure: false,
            sameSite: 'none',
            path: '/',
            maxAge: 8 * 60 * 60 * 10000,
            domain: '192.168.60.108'
        }
        
        res.cookie("token", signed, cookieOptions);
        res.cookie('csrf_token', newToken, cookieOptions);
        
        return res.json({ success: true, message: "login successfully", redirect: NODEBB_BASE_URL, keycloakAccessToken: tokenResponse.access_token });
        

        } catch (err) {
        // eslint-disable-next-line no-console
        console.error('Login error:', err?.response?.data || err?.message || err);
        const status = err?.response?.status || 500
        const message = err?.response?.data?.error_description || err?.response?.data?.error || err?.message || 'Unexpected error';
        return res.status(status).json({ success: false, error: message });
        }

        });
        In the /api/login API, I called the /api/config API, but when I check the /api/config API in Postman using the express.sid generated after login, it never returns the response for that specific user.

        Thanks in advance!

        baluundefined Questo utente è esterno a questo forum
        baluundefined Questo utente è esterno a questo forum
        balu
        scritto su ultima modifica di
        #3

        HenryCharles Thank you. I’m using the session-sharing plugin, but I’m facing an issue. After logging in with SSO, I call NodeBB APIs directly (not the UI). The express.sid is generated, and I use that express.sid to get the CSRF token. However, when I call the /api/config API, the response always gives uid: 0 instead of the logged-in user’s UID.

        julianundefined 1 Risposta Ultima Risposta
        • baluundefined balu

          HenryCharles Thank you. I’m using the session-sharing plugin, but I’m facing an issue. After logging in with SSO, I call NodeBB APIs directly (not the UI). The express.sid is generated, and I use that express.sid to get the CSRF token. However, when I call the /api/config API, the response always gives uid: 0 instead of the logged-in user’s UID.

          julianundefined Questo utente è esterno a questo forum
          julianundefined Questo utente è esterno a questo forum
          julian
          scritto su ultima modifica di
          #4

          balu hey, sorry for the delay, can you post a cURL call to the /api/config endpoint with the cookie?

          I know you posted a code sample (via DM) but the reason I ask for a cURL call is that it is the most straightforward way to test the call and often eliminates errors in header values, etc.

          1 Risposta Ultima Risposta
          Rispondi
          • Topic risposta
          Effettua l'accesso per rispondere
          • Da Vecchi a Nuovi
          • Da Nuovi a Vecchi
          • Più Voti


          Gli ultimi otto messaggi ricevuti dalla Federazione

          • Comandante Virgola :snwfn:undefined
            Comandante Virgola :snwfn:

            @PaoloParti temo che per gli statunitensi sia finita

            per saperne di più

          • ginoundefined
            gino

            @leodurruti 🙏

            per saperne di più

          • Francy 🌻undefined
            Francy 🌻

            @ArtBandini secondo avresti dovuto confermargli che aveva ragione, che siamo violenti, e menarlo sodo.

            per saperne di più

          • Leoundefined
            Leo

            Ok Peskov, grazie dell'informazione, ora però molla il bicchiere, smetti di giocare coi droni e muori

            https://meduza.io/en/feature/2025/09/15/kremlin-says-nato-at-war-with-moscow-days-after-russian-drone-incursions-into-poland-and-romania

            per saperne di più

          • Aure Free Press :verified:undefined
            Aure Free Press :verified:

            Journalist, historian, and author Anne Applebaum:

            "I spent most of the day talking to Ukrainians, some of whom are fighting, some of whom are making drones, some of whom are doing other things to keep their country going. I have to say it doesn't feel like a place that's giving up and it doesn't feel like or look like a place that's shutting down.

            So whatever you've read in the newspaper, whatever you saw on social media, think again when you see this."
            #AureFreePress #News #press #headline

            per saperne di più

          • Mohammed from Gaza 🍉undefined
            Mohammed from Gaza 🍉

            My dear friend @kathimmel, someone sent me this message two days ago, and it perfectly captures my thoughts. Sometimes it's hard to hold on to hope and not give in to despair. But that means they win. Thank you so much for everything you do. May God answer us and reward you abundantly. You are in my heart and mind as well. 🤍🤍🌹🍉💔

            per saperne di più

          • TiTiNoNero :__:undefined
            TiTiNoNero :__:

            Il conflitto in Ukraina è il black friday dei grandi magazzini di armi americane.

            Costa di più rimandare alla fabbrica i proiettili, missili ed esplosivi vicini alla scadenza, che usarli o venderli facendoli pagare a prezzo pieno agli alleati.

            E in più liberi gli scaffali per le armi più fresche.

            per saperne di più

          • Coso, come se chiamaundefined
            Coso, come se chiama

            Fascio yankee fai fagotto, arriva Cerqueti con la P38 👆

            per saperne di più
          • Accedi

          • Accedi o registrati per effettuare la ricerca.
          Powered by NodeBB Contributors
          • Primo post
            Ultimo post