Skip to content

Piero Bosio Social Web Site Personale Logo Fediverso

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

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

Uncategorized
8 3 2
  • 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!

  • 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!

    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.

  • 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!

    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.

  • 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.

    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.

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

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

    balu please continue the conversation here so others may contribute

  • 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.

  • 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.

    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.


Gli ultimi otto messaggi ricevuti dalla Federazione
  • Repeat after me: Do not fill in and sync your government ID data to your Google account

    https://blog.google/products/chrome/enhanced-autofill/

    read more

  • I hope it works out! 🤞🏼

    read more

  • So, I booked a train trip from Seattle to Vancouver. I figure the all-Canadian leg of my trip will be less chaotic. I'll ride to Vancouver on Saturday and then fly to Montreal Saturday night.

    read more

  • So, that doesn't cover my flight out, but my flight home might be affected. Even if my flight itself isn't cancelled, I'll be at an airport with thousands of people whose flights were cancelled. There will be delays in the network. If I do get cancelled, I'd be competing with thousands of other people to get on a flight, bus, or train home.

    read more

  • Then, the Secretary of Transportation said that they were going to start shutting down 10% of air travel through us airports starting Friday.

    https://www.bbc.com/news/articles/c2kp8dex14xo

    read more

  • So, I am flying from Montreal to Seattle for . I leave on Nov 6 and return on Nov 8. I fly from Montreal to Vancouver to Seattle, and then back. All good.

    read more

  • @evan You might need to thee an thenthift.

    read more

  • Better 3D-Printed Bridges Are Possible, With the Right Settings

    The header image above shows a completely unsupported 3D-printed bridge, believe it or not. You’re looking at the bottom of the print. [Make Wonderful Things] wondered whether unsightly unsupported bridges could be improved, and has been busy nailing down remarkably high-quality results by exhaustive testing of different settings.

    It all started when they thought that unsupported bridges looked a lot as though they were made from ropes stretched between two points. Unlike normal layers, these stretched extrusions didn’t adhere to their neighbors. They are too far apart from one another, and there’s no “squish” to them. But could this be overcome?

    His experiments centered mainly around bridge printing speed, temperature, and bridge flow. That last setting affects how much the extrusion from the hot end is adjusted when printing a bridge. He accidentally increased it past 1.0 and thought the results were interesting enough to follow up on; it seemed that a higher flow rate when printing a bridge gave the nudge that was needed to get better inter-line adhesion. What followed was a lot of testing, finally settling on something that provided markedly better results than the stock slicer settings. Markedly better on his test pieces, anyway.
    BF = Bridge flow, BS = Bridge printing speed (in mm/sec)
    The best results seem to come from tweaking the Bridge Flow rate high enough that extrusions attach to their neighbors, printing slowly (he used 10 mm/sec), and ensuring the bridged area is as consistent as possible. There are still open questions, like some residual sagging at corners he hasn’t been able to eliminate, but the results otherwise look great. And it doesn’t even require laying one’s printer on its side!

    All the latest is on the project page where you can download his test models, so if you’re of a mind to give it a try be sure to check it out and share your results. Watch a short video demonstrating everything, embedded just under the page break.

    Thanks to [Hari] for the tip!

    youtube.com/embed/xQBLv3cPUbo?…

    hackaday.com/2025/11/05/better…

    read more
Post suggeriti
  • 0 Votes
    5 Posts
    0 Views
    I hope it works out! 🤞🏼
  • 0 Votes
    1 Posts
    0 Views
    Better 3D-Printed Bridges Are Possible, With the Right SettingsThe header image above shows a completely unsupported 3D-printed bridge, believe it or not. You’re looking at the bottom of the print. [Make Wonderful Things] wondered whether unsightly unsupported bridges could be improved, and has been busy nailing down remarkably high-quality results by exhaustive testing of different settings.It all started when they thought that unsupported bridges looked a lot as though they were made from ropes stretched between two points. Unlike normal layers, these stretched extrusions didn’t adhere to their neighbors. They are too far apart from one another, and there’s no “squish” to them. But could this be overcome?His experiments centered mainly around bridge printing speed, temperature, and bridge flow. That last setting affects how much the extrusion from the hot end is adjusted when printing a bridge. He accidentally increased it past 1.0 and thought the results were interesting enough to follow up on; it seemed that a higher flow rate when printing a bridge gave the nudge that was needed to get better inter-line adhesion. What followed was a lot of testing, finally settling on something that provided markedly better results than the stock slicer settings. Markedly better on his test pieces, anyway.BF = Bridge flow, BS = Bridge printing speed (in mm/sec)The best results seem to come from tweaking the Bridge Flow rate high enough that extrusions attach to their neighbors, printing slowly (he used 10 mm/sec), and ensuring the bridged area is as consistent as possible. There are still open questions, like some residual sagging at corners he hasn’t been able to eliminate, but the results otherwise look great. And it doesn’t even require laying one’s printer on its side!All the latest is on the project page where you can download his test models, so if you’re of a mind to give it a try be sure to check it out and share your results. Watch a short video demonstrating everything, embedded just under the page break.Thanks to [Hari] for the tip!youtube.com/embed/xQBLv3cPUbo?…hackaday.com/2025/11/05/better…
  • I taught the tariff

    Uncategorized
    3
    0 Votes
    3 Posts
    0 Views
    @evan You might need to thee an thenthift.
  • Sweet!

    Uncategorized freebsd
    3
    0 Votes
    3 Posts
    0 Views
    @stefano I will!