0

I am bulding FullStack App with React and Express. I want to make auth with JWT and i have trouble with send a cookie to the browser. When i clicked submit in form everything is fine cuz i can see a new user in my db but i need a cookie in my browser with jwt That my code: React:

import React from 'react';
import { useForm } from 'react-hook-form';
import Input from '../../styledComponents/Input';
import Button from '../../styledComponents/Button';
import Link from '../../styledComponents/Link';
import FlexWrapper from '../../styledComponents/FlexWrapper';
import InputWrapper from '../../styledComponents/InputWrapper';
import Span from '../../styledComponents/Span';
import axios from 'axios';
const Form = () => {
    const { register, handleSubmit } = useForm();

    const onSubmit = async ({ email, password }) => {
        try{
            const res = await axios.post('http://localhost:5000/signup', {
                email,
                password
              })
        }
        catch (err) {
            console.log(err)
        }
    }

    return (
        <form onSubmit={handleSubmit(onSubmit)}>
            <InputWrapper>
                <Input type='text' placeholder='Email' name='email' ref={register} />
                <Span>Email</Span>
            </InputWrapper>
            <InputWrapper>
                <Input type='password' placeholder='Password' name='password' ref={register} />
                <Span>Password</Span>
            </InputWrapper>
            <FlexWrapper direction='row' justify='center' align='center' width='100%'>
                <Link href='/'>Already have account?</Link>
            </FlexWrapper>
            <FlexWrapper direction='row' justify='space-between' align='center' width='100%'>
                <Button 
                bgColor={({theme}) => theme.colors.main}
                color={({ theme }) => theme.colors.white}
                >Sign Up</Button>
                <Button 
                bgColor={({theme}) => theme.colors.white} 
                color={({ theme }) => theme.colors.black}
                >Guest</Button>
            </FlexWrapper>
        </form>
    )
}

export default Form;

And Express: Server.js:

const express = require('express');
const app = express();
const port = 5000;
const mongoose = require('mongoose');
const authRoutes = require('./routes/authRoutes');
const cookieParser = require('cookie-parser');
const cors = require('cors');

// middlewares
app.use(express.json());
app.use(cookieParser());
app.use(cors())

// database connection
const dbURI = 'mongodb+srv://[HIDE]@weatherapp.ye3be.mongodb.net/weather-app-users';
mongoose.connect(dbURI, { useNewUrlParser: true, useUnifiedTopology: true, useCreateIndex: true })
    .then(result => app.listen(port, () => {
        console.log(`I am listening a port ${port}`)
    }))
    .catch(err => console.log(err))

app.get('/', (req, res) => {
    res.send('sdaasda')
})

app.use(authRoutes);

and my controller:

const User = require('../models/User');
const jwt = require('jsonwebtoken');

// handle errors
const handleErrors = (err) => {
  let errors = {
    email: '',
    password: ''
  }
  // duplicate error code
  if(err.code === 11000){
    errors.email = 'That email is already registered';
    return errors;
  }

  // validation errors
  if(err.message.includes('user validation failed')) {
    Object.values(err.errors).forEach(({ properties }) => {
      errors[properties.path] = properties.message
    })
  }
  return errors;
}

// create json web token
const maxAge = 3 * 24 * 60 * 60;
const createToken = (id) => {
  return jwt.sign({ id }, 'test', {
    expiresIn: maxAge
  });
};


module.exports.signup_post = async (req, res) => {
  const { email, password } = req.body;

  try{
    const user = await User.create({ email, password });
    const token = createToken(user._id);
    res.cookie('jwt', token, { httpOnly: true, maxAge: maxAge * 1000 });
    res.status(201).json({ user: user._id });
    console.log(user._id)
  }
  catch (err) {
    const errors = handleErrors(err);
    res.status(400).json({ errors })
  }
}

module.exports.login_post = async (req, res) => {
    res.send('Post - Login Page');
}

I should be able to see a cookie in the browser after post request but i cant see that in application -> cookies in the browser...

INeedYourHelp
  • 131
  • 1
  • 2
  • 8

3 Answers3

1

Express:

router.use((req, res, next) => {
  res.header('Access-Control-Allow-Headers', 'Origin, X-Requiest-With, Content-Type, Accept');
  if (env === 'local') {
    res.header('Access-Control-Allow-Credentials', true);
    res.header('Access-Control-Allow-Origin', 'http://localhost:3000');
  }
  res.header('Access-Control-Allow-Methods', 'GET, PUT, POST, DELETE, HEAD, OPTIONS');
  next();
});

React with axios

import axios from 'axios';

axios.defaults.withCredentials = true;

...

export async function login(val) {
  const response = await axios.post(`${originAndPort}/login`, val)
    .then((res) => {
      // your code here   
      return res                                           
    })
    .catch((error) => {
      // your error here  
    });
  return response;
}

more info here: Make Axios send cookies in its requests automatically

0

if you want store your data in cookie trty

import cookie from 'js-cookie';

cookie.set('nameForData',data);
krimo
  • 666
  • 2
  • 8
  • 27
-1

A more modern approach would be using localStorage or sessionStorage you can store data in the storage from frontend directly based on the response of api you can try code below:

    const onSubmit = async ({ email, password }) => {
        fetch(http://localhost:5000/signup, {
             method: "POST", 
             header: {content-type: "application/json"},
             body: {email: email, password: password}}
    ).then((res)=> res.json();
      console.log(res);
    localStorage.setItem('testObject', JSON.stringify(res));
)
        
    }