0

I have a very challenging problem. I just started using JWT. I do the login and I send the token as a JSON response to the client. I save that to sessionStorage and then I want to use the token to access the protected route which is basically what the user should see when logs in.

The problem is that I should also send in the token in the header somehow from the client between these. Right now I just do window.location.pathname = '/LimeLINE/chatroom'to that route.

I feel like there should be an extra step to do this, like a get on the client?

So step 1, login on the client:

// Login POST 
    $('#frm-login').submit(function (e) {
        event.preventDefault()
        $('button').text('Please wait ...').prop('disabled')
        $.ajax({
            url: "/login-user",
            type: "POST",
            data: $('#frm-login').serialize(),
            dataType: "json"
        }).always(function (response) {
            $('button').text('Logging in').prop('disabled')
            console.log("Login", response)
            if (response.status == "error") {
                $('button').removeClass('lime').addClass('red').text('Log in failed. Try again.');
                return
            }
            //console.log(response)
            const token = response.token;
            sessionStorage.setItem(token, token);
            window.location.pathname = '/LimeLINE/chatroom'
        })
    })

So step 2, login on the server:

/********************* LOGIN *********************/

app.post('/login-user', (req, res) => {
    user.loginUser(req.body, (err, jResult) => {
        if (err) {
            return res.send(jResult)
        }
        let token = jwt.sign({
            user: jResult,
        }, "supersecret", (err, token) => {
            if (err) {
                return res.statusCode(500)
            }
        })
        console.log(token)
        return res.json({
            token: token
        })
        //add other headers here...
    })
})

and the protected route:

// *********************   MAIN PAGE *************************

app.get('/LimeLINE/chatroom', verifyToken, (req, res) => {
    jwt.verify(req.token, "supersecret", (err, authData) => {
        if (err) {
            return res.status(403).json({
                message: "No token found"
            });
        } else {
            try {
                var sMainHtml = fs.readFileSync(__dirname + '/html/main.html', 'utf8')

            } catch (e) {
                console.log(e)
                return res.sendStatus(500)
            }
            return res.send(sMainHtml);
            /*return res.json({
                authData
            });*/
        }
    })
})
July333
  • 251
  • 1
  • 6
  • 15
  • Is the server setting the token as a cookie on the response? If you set the token as a cookie, then any browser request made to the same domain the cookie is set for will including that cookie on the request automatically. Even ajax requests can be made to do the same thing if you set the `withCredentials` on the xhr to true. – Taplar May 16 '18 at 16:39
  • no, it is sent as JSON. I have read that cookies are not so favorable nowadays. – July333 May 16 '18 at 16:42
  • There's nothing wrong with cookies, per say. Especially around authentication. The primary thing to be aware though is it is recommended to set the HttpOnly header (https://www.owasp.org/index.php/HttpOnly) so that javascript does not have the ability to access them. – Taplar May 16 '18 at 16:44
  • Related: https://stackoverflow.com/questions/3393854/get-and-set-a-single-cookie-with-node-js-http-server – Taplar May 16 '18 at 16:46
  • thank you, but I want to go this way, there is obviously a solution for this. – July333 May 16 '18 at 16:53

0 Answers0