Logout User from external website

Plugin Requests
  • Re: User Logout from external application

    Hi,

    I am new using nodebb, so I created a subdomain with the forum and it is connected with a Wordpress site with the SSO Wordpress plugin.

    I managed to logout the user from wordpress when he logs out from nodebb via a POST Request to wordpress. But I can't do the oposit thing, I mean I can't remove session on nodebb when I logout on Wordpress.

    I have created a custom plugin using the quickstart plugin, I created a route in API but I am not able to find the session to remove...

    I am reaching this API method:

    plugin.addRoutes = async ({ router, middleware, helpers }) => {
            const middlewares = [
                    middleware.ensureLoggedIn,                      // use this if you want only registered users to call this route
                    // middleware.admin.checkPrivileges,    // use this to restrict the route to administrators
            ];
    
            routeHelpers.setupApiRoute(router, 'get', '/quickstart/:user_slug', middlewares, async (req, res) => {
                    // Here I can search for user based on user_slug param
                    const uid = await User.getUidByUserslug(req.params.user_slug);
    
                    console.log('UID: ' + uid);
    
                    // At this point I need to delete the users Session("sess:id")
                    // How I get the "id"
                    const result = await db.get('sess:id');
                    console.log(result);
    
                    helpers.formatApiResponse(200, res, {
                            status: 'success' 
                    });
            });
    };
    
    

    Can anyone to give me a hint on how can I manage this?
    Thanks in advance.

  • @devdevov If you want the user to log out of NodeBB, they'll just need to send a POST request to /logout. It doesn't have to be a page navigation I think, just an XHR will do.

  • @julian thanks for reply!

    I have a question which parameters should I send with the POST request?

    Is there a documentation about this?

    I found revoke a user session in the Nodebb Write API, but I don't know how to get the second parameter "UUID" of the user.

    Thanks!

  • @devdevov You don't need to send anything, the way it works is it grabs the session from the cookie (this is not api v3, just the regular page API), and logs out the user.

  • @julian ok, I tried to send an XHR request but got 403...

    var http = new XMLHttpRequest();
    var params = 'orem=ipsum&name=binny';
    http.open('POST', 'https://forum.example.com/logout', true);
    
    http.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
    http.setRequestHeader('Authorization', 'Bearer <TOKEN>');
    
    http.onreadystatechange = function() {
        if(http.readyState == 4 && http.status == 200) {
            alert(http.responseText);
        }
    }
    http.send(params);
    
  • @julian Yesterday I found a workaround. I don't think that it is the cleanest way to do it ...

    On the wordpres site I make a Curl POST Request:

    $req = curl_init();
    curl_setopt($req, CURLOPT_URL, "https://forum.example.com/api/v3/plugins/quickstart/<user_slug>?_uid=<admin_uid>");
    curl_setopt($req, CURLOPT_PORT , 443);
    curl_setopt($req, CURLOPT_HTTPHEADER, array("Content-Type: application/json", "Authorization: Bearer <TOKEN>"));
    
    $daata = curl_exec($req);
    if(!curl_errno($req)){
      $info = curl_getinfo($req);
      echo 'Took ' . $info['total_time'] . ' seconds to send a request to ' . $info['url'];
    } else {
      echo 'Curl error: ' . curl_error($req);
    }
    
    

    On the Nodebb plugin I receive the request and connect directly to mongodb and remove the session of the requested user:

    routeHelpers.setupApiRoute(router, 'get', '/quickstart/:user_slug', middlewares, async (req, res) => {
    
                    const uri = "mongodb://<user>:<pass>@<host>:27017";
                    const client = new MongoClient(uri);
                    const uid = await User.getUidByUserslug(req.params.user_slug);
    
                    MongoClient.connect(uri, async function(err, db) {
                            if (err) throw err;
                            const dbo = db.db("nodebb");
                            await dbo.collection("sessions").find({}).forEach(function(doc) {
                                    const data = JSON.parse(doc.session);
                                    if(data.passport.user == uid) {
                                            dbo.collection("sessions").deleteOne({'_id': doc._id})
                                            console.log('Removed');
                                    }
                            });
                            db.close();
                    });
    
                    helpers.formatApiResponse(200, res, {
                            status: 200,
                            message: 'User successfully logged out.'
                    });
            });
    

    This way it logs out. I think that there must be another solution for this.

  • @julian So, is this the right way to logout a user from external website?

    revoke a user session

    is there an example?

  • If you can, yes... that would work if you had the session uuid, which you might not.

    Essentially, when you use SSO to log in a user via a third-party authenticator, NodeBB is maintaining that session, not the other site. That's why it's not assumed behaviour that if you log out of the other site, that you also log out of NodeBB.

    If the user wants to log out of the forum, they'd have to log out themselves via the NodeBB logout button.

    That said, in the end the logout is literally just a POST request... so in your site, you could code in a XHR that calls POST https://your.nodebb.site/logout and that would log out the user 😄


Suggested Topics