madmeatballs
madmeatballs

Reputation: 73

Access token in cookies but validation can't detect it in react.js(axios), works in postman

so I made a login function which generates an access token in cookies. But when I do validation for the a page the page doesn't detect the cookie, in postman it works but in react it doesn't.

Here is my code, sorry if my explanation is kind of confusing.

jwt.js file

const { sign, verify } = require('jsonwebtoken');

const createTokens = (user) => {
    const accessToken = sign(
        { username: user.username, id: user.user_id }, 
        'secret'
    );
    return accessToken;
};

const validateToken = (req, res, next) => {
    const accessToken = req.cookies['access-token']

    if (!accessToken) 
        return res.status(400).json({error: 'User not authenticated!'})

    try {
         const validToken = verify(accessToken, 'secret')
         req.user = validToken;
         if(validToken) {
            req.authenticated = true
            return next();
         }
    } catch(err) {
        console.log(req.cookies);
        return res.status(400).json({error: err})
    }
};

module.exports = { createTokens, validateToken };

routes for users.js

const express = require('express');
const router = express.Router();
const { Users } = require('../models');
const bcrypt = require('bcrypt');

const { createTokens, validateToken } = require('../controllers/jwt');

router.get('/', validateToken, async (req, res) => {
    const userList = await Users.findAll()
    res.json(userList);
});

router.get('/:id', validateToken, async (req, res) => {
    const id = req.params.id
    const user = await Users.findByPk(id);
    res.json(user);
});

router.post('/', validateToken, async (req, res) => {
    const { username, 
            email, 
            password, 
            first_name,
            last_name } = req.body;
    bcrypt.hash(password, 10).then((hash) => {
        Users.create({
            username: username,
            email: email,
            password: hash,
            first_name: first_name,
            last_name: last_name
        });
        res.json('User successfully added')
    });
});

router.post('/login', async (req, res) => {
    const { username, password } = req.body;

    const user = await Users.findOne({ where: {username: username}});

    if(!user) res.status(400).json({error: `Username does not exist!`});

    bcrypt.compare(password, user.password).then((match) => {
        if(!match) res.status(400).json({error: 'Wrong password!'})

        const accessToken = createTokens(user);

        res.cookie('access-token', accessToken, {
            maxAge: 60*60*24*30*1000, //30 days
            secure: process.env.NODE_ENV === 'production' ? true : false,
            httpOnly: process.env.NODE_ENV === 'production' ? true : false,
            sameSite: 'strict',
            path: '/'
        });

        user.password = undefined;

        res.json(accessToken);
    })
});

module.exports = router;

here is how I call it without the validateToken, what am I missing? lol. Really confused right now.

    const [ usersList, setUsersList ] = useState ([]);

    useEffect(() => {
      axios.get('http://localhost:4000/users').then((res) => {
        setUsersList(res.data)
      })
    }, []);

Upvotes: 0

Views: 736

Answers (1)

Michal Trojanowski
Michal Trojanowski

Reputation: 12322

Make sure you are sending credentials when calling the endpoint with axios. See this answer: https://stackoverflow.com/a/43178070/1712294 to check how to do it.

Upvotes: 1

Related Questions