Spacc BBS Spacc BBS
    • Categorie
    • Recenti
    • Tag
    • Popolare
    • Mondo
    • Utenti
    • Gruppi
    • Registrati
    • Accedi
    La nuova BBS è in fase Alpha. I post precedenti al 22 luglio 2024 potrebbero non essere trasferibili, ma rimarranno disponibili per la lettura su /old/.

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

    Pianificato Fissato Bloccato Spostato Uncategorized
    8 Post 3 Autori 22 Visualizzazioni
    Caricamento altri post
    • 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.
    • balu@community.nodebb.orgB Questo utente è esterno a questo forum
      balu@community.nodebb.org
      ultima modifica di

      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!

      H balu@community.nodebb.orgB 2 Risposte Ultima Risposta Rispondi Cita 0
      • H Questo utente è esterno a questo forum
        henrycharles@community.nodebb.org @balu@community.nodebb.org
        ultima modifica di

        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 Rispondi Cita 0
        • balu@community.nodebb.orgB Questo utente è esterno a questo forum
          balu@community.nodebb.org @balu@community.nodebb.org
          ultima modifica di

          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.

          julian@community.nodebb.orgJ 1 Risposta Ultima Risposta Rispondi Cita 0
          • julian@community.nodebb.orgJ Questo utente è esterno a questo forum
            julian@community.nodebb.org @balu@community.nodebb.org
            ultima modifica di

            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 Cita 0
            • balu@community.nodebb.orgB Questo utente è esterno a questo forum
              balu@community.nodebb.org
              ultima modifica di

              julian Thank you for your reply, I am DM my question.

              julian@community.nodebb.orgJ 1 Risposta Ultima Risposta Rispondi Cita 0
              • julian@community.nodebb.orgJ Questo utente è esterno a questo forum
                julian@community.nodebb.org @balu@community.nodebb.org
                ultima modifica di

                balu please continue the conversation here so others may contribute

                1 Risposta Ultima Risposta Rispondi Cita 0
                • balu@community.nodebb.orgB Questo utente è esterno a questo forum
                  balu@community.nodebb.org
                  ultima modifica di

                  Thanks julian for your reply, and sorry for my poor communication earlier. My main issue is that I’m using SSO with Cognito. After a successful login, I call the /api/config API using the generated express.sid, but the response always returns uid: 0. My question is: how is the express.sid generated? I’m using React.js for the frontend, not the default NodeBB UI.

                  julian@community.nodebb.orgJ 1 Risposta Ultima Risposta Rispondi Cita 0
                  • julian@community.nodebb.orgJ Questo utente è esterno a questo forum
                    julian@community.nodebb.org @balu@community.nodebb.org
                    ultima modifica di

                    balu the cookie is generated by the express-cookie package.

                    If you're receiving uid 0 it means the cookie isn't being passed in correctly.

                    1 Risposta Ultima Risposta Rispondi Cita 0
                    • Primo post
                      Ultimo post