Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Error: A cross-origin error was thrown. Error: a secret should be set

Tags:

reactjs

I'm following a course to make an e-commerce website and when I try to sign a user up, I receive this error: enter image description here The instructor cloned my repo and received no errors however I am receiving an error whenever I try to sign up or sign in.

How can I solve this? Any help would be really appreciated. Perhaps there's an issue with the errorHandler file that I'm using to handle the error.

controllers/auth.js

const User = require('../models/user')
const jwt = require('jsonwebtoken') // to generate signed token
const expressJwt = require('express-jwt') // for authorization check
const { errorHandler } = require('../helpers/dbErrorHandler')

exports.signup = (req, res) => {
    console.log("req.body", req.body)
    // signs up new user
 const user = new User(req.body)
 user.save((err, user) => {
if(err) {
    return res.status(400).json({
        err: errorHandler(err)
    })
}
user.salt = undefined 
user.hashed_password = undefined

res.json({
    user 
 })
 })
}

exports.signin = (req, res) => {
// find user based on email
const { email, password } = req.body 
User.findOne({email}, (err, user) => {
if (err || !user) {
    return res.status(400).json({
        error: 'User with that email does not exist.'
    })
}
// if user is found, ensure email & password match
// create authenticate method in user model
if (!user.authenticate(password)) {
    return res.status(401).json({
error: 'Email and password dont match'
    })
}
// generate signed token with user id and secret
const token = jwt.sign({_id: user._id}, process.env.JWT_SECRET)

// persist token as 't' in cookie with expiry date
res.cookie('t', token, {expire: new Date() + 9999 })

// return response with user & token to frontend client
const {_id, name, email, role} = user
return res.json({token, user: {_id, email, name, role}})
})
}

exports.signout = (req, res) => {
    res.clearCookie('t')
    res.json({ message: "Signout success" })
}

exports.requireSignin = expressJwt({
secret: process.env.JWT_SECRET,
userProperty: 'auth'
})

exports.isAuth = (req, res, next) => {
    let user = req.profile && req.auth && req.profile._id == req.auth._id
if(!user) {
    return res.status(403).json({
        error: "Access denied"
    })
}
    next()
}

exports.isAdmin = (req, res, next) => {
    if (req.profile.role === 0) {
        return res.status(403).json({
        error: 'Admin resource! Access denied'
        })
    }
    next()
}

The error message in the console:

  throw new MongooseError('The `uri` parameter to `openUri()` must be a ' +
    ^
Error [MongooseError]: The `uri` parameter to `openUri()` must be a string, got "undefined". Make sure the first parameter to `mongoose.connect()` or `mongoose.createConnection()` is a string.
like image 300
SK7 Avatar asked Nov 06 '22 07:11

SK7


1 Answers

You have uncaught exceptions in Components Signup and Signin.

// Signin.js
const clickSubmit = (event) => {
    event.preventDefault()
    setValues({ ...values, error: false, loading: true })
    signin({ email, password }).then(data => {
        if (data.error) {
            setValues({ ...values, error: data.error, loading: false })
        } else {
            authenticate(data, () => {
                setValues({
                    ...values,
                    redirectToReferrer: true
                })
            })
        }
    }).catch(exc => {
        console.error("+++ exc signin: ", exc)
        // we log error 
        setValues({ ...values, error: exc.message, loading: false })
    });
}



// Signup.js
const clickSubmit = event => {
    event.preventDefault();
    setValues({ ...values, error: false });
    signup({ name, email, password }).then(data => {
        console.log("++ data: ", data);

        // if you need to check error from backend
        // else all exceptions are captured in catch block 
        if (data.error) {
            setValues({ ...values, error: data.error, success: false });
        } else {
            setValues({
                ...values,
                name: '',
                email: '',
                password: '',
                error: '',
                success: true
            });
        }
    }).catch(exc => {
        console.error('++ exc: ', exc);

        setValues({ ...values, error: exc.message, success: false });
    })
};

Then in auth/index.js, only return fetch promise and let calling function handle exception.

 // cors mode to allow cross-origin 
 export const signup = (user) => {
    return fetch(`${API}/signup`, {
        method: "POST",
        mode: 'cors',
        headers: {
            Accept: 'application/json',
            "Content-Type": "application/json"
        },
        body: JSON.stringify(user)
    })
        .then(response => {
            return response.json()
        })

};



// mode cors to allow cross-origin access
export const signin = (user) => {
    return fetch(`${API}/signin`, {
        method: "POST",
        mode: 'cors',
        headers: {
            Accept: 'application/json',
            "Content-Type": "application/json"
        },
        body: JSON.stringify(user)
    })
        .then(response => {
            return response.json()
        })

}

On backend end, make sure these keys are set process.env.JWT_SECRET or you can either use a default value in case key is not set or exit app on startup if important keys are not set.

process.env.JWT_SECRET || 'default_ket'

You need to create .env file at root of ecommerce-back and in it

DATABASE=mongodb://localhost:27017/Ecommerce
JWT_SECRET=secret

Here, it is Mongo is running on default port and your database name is Ecommerce, otherwise set values according to your setup.

like image 50
artfulbeest Avatar answered Nov 15 '22 08:11

artfulbeest