GET information from user in database - javascript

I am making full stack app and learn from tutorials and videos . I have a problem with GET request to get information about user which is login in the system. I use Postman to check the requests. When I add user with /login , the Postman look user's accesstoken code. I copy his code and paste it in authorization key in headers in Postman and when I change the URL in localhost to /infor to get information about this user and send it. But it say me "Invalid Authentication". I can't find the wrong. I think the problem is in controllers/userCtrl.js in getUser function. Can you help me?
I put the code:
server.js
require('dotenv').config()
const express = require('express')
const mongoose = require('mongoose')
const cors = require('cors')
const fileUpload = require('express-fileupload')
const cookieParser = require('cookie-parser')
const app = express()
app.use(express.json())
app.use(cookieParser())
app.use(cors())
// Use temp files instead of memory for managing the upload process.
app.use(fileUpload({
useTempFiles: true
}))
// Routes
app.use('/user', require('./routes/userRouter'))
// Connect to Mongodb
const URL = process.env.MONGO_URL
mongoose.connect(URL,{
useCreateIndex: true,
useFindAndModify: false,
useNewUrlParser: true,
useUnifiedTopology: true
}, err =>{
if(err) throw err;
console.log('Connected to MongoDB')
})
const PORT = process.env.PORT || 5000
app.listen(PORT, () => {
console.log('Server is running on port', PORT)
})
.env
MONGO_URL = ***********
ACCESS_TOKEN_SECRET = ***********
REFRESH_TOKEN_SECRET = *************
routes/userRouter.js
require('dotenv').config()
const express = require('express')
const mongoose = require('mongoose')
const cors = require('cors')
const fileUpload = require('express-fileupload')
const cookieParser = require('cookie-parser')
const app = express()
app.use(express.json())
app.use(cookieParser())
app.use(cors())
// Use temp files instead of memory for managing the upload process.
app.use(fileUpload({
useTempFiles: true
}))
// Routes
app.use('/user', require('./routes/userRouter'))
// Connect to Mongodb
const URL = process.env.MONGO_URL
mongoose.connect(URL,{
useCreateIndex: true,
useFindAndModify: false,
useNewUrlParser: true,
useUnifiedTopology: true
}, err =>{
if(err) throw err;
console.log('Connected to MongoDB')
})
const PORT = process.env.PORT || 5000
app.listen(PORT, () => {
console.log('Server is running on port', PORT)
})
models/userModel.js
const mongoose = require('mongoose')
const userSchema = new mongoose.Schema({
name: {
type: String,
required: true,
trim: true
},
email: {
type: String,
required: true,
unique: true
},
password: {
type: String,
required: true,
},
role: {
type: Number,
default: 0
},
cart: {
type: Array,
default: []
}
}, {
timestamps: true
})
module.exports = mongoose.model('Users', userSchema)
middleware/auth.js
const jwt = require('jsonwebtoken')
const auth = (req, res, next) => {
try{
const token = req.header("Authorization")
if(!token) return res.status(400).json({ msg: "Invalid Authentication" })
jwt.verify(token, process.env.ACCESS_TOKEN_SECRET, (err, user) => {
if(!err) return res.status(400).json({msg: "Invalid Authentication" })
req.user = user
next()
})
} catch (err) {
return res.status(500).json({msg: err.message})
}
}
module.exports = auth
controllers/userCtrl.js
const Users = require('../models/userModel')
const bcrypt = require('bcrypt')
const jwt = require('jsonwebtoken')
const userCtrl = {
register: async (req, res) => { // async before a function means one simple thing: a function always returns a promise.
try{
const { name, email, password } = req.body
const user = await Users.findOne({ email }) // wait until the promise resolves
if(user) return res.status(400).json({msg: "The email already exists"})
if(password.length < 6)
return res.status(400).json({msg: "Password is at least 6 characteres long."})
//Password encryption
const passwordHash = await bcrypt.hash(password, 10)
const newUser = new Users({
name, email, password: passwordHash
})
// save mongodb
await newUser.save()
//then create jsonwebtoken to authentication
const accesstoken = createAccessToken({ id: newUser._id })
const refreshtoken = createRefreshToken({ id: newUser._id })
res.cookie('refreshtoken', refreshtoken, {
httpOnly: true,
path: '/user/refresh_token'
});
res.json({accesstoken})
} catch(err){
return res.status(500).json({msg: err.message})
}
},
login: async (req, res) => {
try{
const {email, password} = req.body;
const user = await Users.findOne({email})
if(!user) return res.status(400).json({msg: "User does not exist."})
const isMatch = await bcrypt.compare(password, user.password)
if(!isMatch) return res.status(400).json({msg: "Incorrect password"})
// if login success, create access token and refresh token
const accesstoken = createAccessToken({ id: user._id })
const refreshtoken = createRefreshToken({ id: user._id })
res.cookie('refreshtoken', refreshtoken, {
httpOnly: true,
path: '/user/refresh_token'
});
res.json({accesstoken})
} catch(err){
return res.status(500).json({msg: err.message})
}
},
logout: async (req, res)=> {
try{
res.clearCookie('refreshtoken', {path: '/user/refresh_token'})
return res.json({msg: "Logged out"})
}catch(err){
return res.status(500).json({msg: err.message})
}
},
refreshToken: (req, res) => {
try{
const rftoken = req.cookies.refreshtoken
if(!rftoken) return res.status(400).json({msg: "Please login or Register"})
jwt.verify(rftoken, process.env.REFRESH_TOKEN_SECRET, (err, user) => {
if(err) return res.status(400).json({msg: "Please login or Register"})
const accesstoken = createAccessToken({id: user.id})
res.json({ accesstoken })
})
}catch (err) {
return res.status(500).json({msg: err.message})
}
},
getUser: async (req, res) => { // problem
try{
const user = await (await Users.findById(req.user.id)).isSelected('-password')
if(!user) return res.status(400).json({ msg: "Useer does not exist."})
res.json(req.user)
}catch (err) {
return res.status(500).json({msg: err.message})
}
}
}
const createAccessToken = (user) => {
return jwt.sign(user, process.env.ACCESS_TOKEN_SECRET, { expiresIn: '1d' })
}
const createRefreshToken = (user) => {
return jwt.sign(user, process.env.REFRESH_TOKEN_SECRET, { expiresIn: '7d' })
}
module.exports = userCtrl

For your middle ware for getting the token (auth function)
const { authorization } = req.headers
if (!authorization) {
console.log('[No Authorization Code]');
return res.status(401).send({ message: 'Unauthorized' });
}
if (!authorization.startsWith('Bearer')) {
console.log('[Authorization need to start with Bearer]')
return res.status(401).send({ message: 'Unauthorized' });
}
const split = authorization.split('Bearer ')
if (split.length !== 2) {
console.log('[Invalid Authorization Param')
return res.status(401).send({ message: 'Unauthorized' });
}
const token = split[1] //this is your token to use with jwt.verify
When you sending the token in postman, select Bearer Token
When you start creating your frontend, the codes should be equivalent to the following fetch request
fetch('/api/path', { method: 'GET', headers: { "Authorization": `Bearer ${token}`}}).(res => res.json())
May change method to your desire method (e.g get or post), and the token will be the the jwt token

Related

User is not authenticated jswtoken

I have created a login page and a about page the user will only access the about page if the user is logged in.
I am trying to authenticate the user by using the tokens generated while signing in, but the token is not getting authenticated even after signing in with the correct credentials. I don't know what is the problem?
This is code to my sign-in and token generating method
const express = require("express");
const { default: mongoose } = require("mongoose");
const router = express.Router();
const bcrypt = require("bcrypt");
const jwt = require("jsonwebtoken");
require("../db/conn");
const User = require("../model/userSchema");
const cookieParser = require('cookie-parser');
const Authenticate = require("../middleware/authenticate");
router.use(cookieParser());
//LOgin route
router.post("/signin", (req, res)=>{
if(!req.body.email || !req.body.password){
return res.status(400).json({error: "Plz fill the required data"});
}else{
bcrypt.hash(req.body.password, 12, function (err, hash) {
User.findOne({email: req.body.email}, function (err, foundUser) {
if(err){
console.log(err);
}else{
if(foundUser){
bcrypt.compare(req.body.password, foundUser.password, function (err, result) {
if(result){
return res.json({message: "successfully log in"})
}else{
return res.json({message: "incorrect password"});
}
});
const email = req.body.email;
const token = jwt.sign(
{ user_id: foundUser._id, email },
process.env.TOKEN_KEY,
{
expiresIn: "720h",
}
);
foundUser.tokens = foundUser.tokens.concat({token: token});
foundUser.save();
// res.status(200).json(foundUser);
console.log(foundUser);
}else{
return res.status(400).json({message: "user not found"});
};
}
})
})
}
});
//about us page
router.get("/about", Authenticate, function (req, res) {
console.log("about running");
res.send(req.rootUser);
});
module.exports = router;
this is the code to authenticate the user
require("dotenv").config({path: "./config.env"});
const jwt = require("jsonwebtoken");
const User = require("../model/userSchema");
const Authenticate = async(req, res, next) =>{
try {
const token = req.cookies.jwtoken;
const verifyToken = jwt.verify(token, process.env.TOKEN_KEY);
const rootUser = await User.findOne({ _id: verifyToken._id, "tokens.token": token});
if(!rootUser) {
throw new Error("User not found")
}
req.token = token;
req.rootUser = rootUser;
req.userID = rootUser._id;
next();
} catch (err) {
console.log(err);
return res.status(401).send("Unauthorized: No token provided");
}
}
module.exports = Authenticate;
This is react based code of: About-page to display it or not based on user's authenticity.
const navigate = useNavigate();
const callAboutPage = async() =>{
try {
const res = await fetch("/about",{
method: "GET",
headers: {
Accept: "application/json",
"Content-Type" : "application/json"
},
credentials: "include"
});
const data = await res.json();
console.log(data);
if(!res.status === 200){
const error = new Error(res.error);
throw error;
}
} catch (err) {
console.log(err);
navigate("/login");
}
}
As said in the comment looks like there is a issue on the process for setting up the jwtoken, and when you sign in, you just need to find the user and compare the password, there is no need to do the hash with Bcrypt, since you're not registing new user, for example, i will use Async/await instead of callback function, in order for you to read it much more easier:
//Login route
router.post("/signin", async (req, res)=> {
const { reqEmail, reqPassword } = req.body; //destructuring so less thing to write at the next step
if(!reqEmail || !reqPassword) {
return res.status(400).json({message: "Plz fill the required data"});
}
try {
const foundUser = await User.findOne({email: reqEmail})
if(!foundUser) {
return res.status(400).json({message: "Wrong username or password!"})
}
const result = await bcrypt.compare(reqPassword, foundUser.password);
if(!result){
return res.json({message: "Wrong username or password!"})
} else {
const accessToken = jwt.sign(
{ user_id: foundUser._id, email: foundUser.email},
process.env.TOKEN_KEY,
{ expiresIn: "720h",}
);
// I am confuse what are you trying to do here, in your place I would set up on the cookie since you do that on your authentification.
res.cookie("jwt", accessToken, {
maxAge: 60000, // 60 sec for testing
httpOnly: true,
sameSite: false, //false only for dev
secure: false, //false only for dev
})
res.status(200).json(foundUser);
};
} catch (error) {
return res.status(500).json({message: `${error}`})
}
Than the authentification middleware :
// ...
const Authenticate = (req, res, next) => {
const accessToken = req.cookies.jwt
if(!accessToken) {
return res.status(401).json({error: "Unauthorized: No token provided"});
}
try {
const user = jwt.verify(accessToken, process.env.TOKEN_KEY)
if(user) {
req.user = user
return next();
}
} catch (error) {
return res.status(403).json({error: "Forbidden token error"})
}
}
about page component it's simple for now since you don't manage any state
const navigate = useNavigate();
const callAboutPage = async() =>{
try {
const res = await fetch("/about",{
headers: {
"Content-Type": "application/json"
},
credentials: "include"
});
if(res.status === 200){
const data = await res.json();
// set up the state for rendering
console.log(data);
} else {
// you can also create a state to catch the error message from the backend, in this case the response json should be move to above the if statement.
throw new Error("You must log in to get access")
// than you can display this error message, or from the backend using state for this bloc, and the catch bloc
// navigate to /login
}
} catch (err) {
console.log(err);
navigate("/login");
}
}
router.use(cookieParser());
Try to use cookieParser with app.use instead. (app from express instense)
Expample:
const app = express();
app.use(cookieParser());
and try to put it before server listening in index.js or app.js file.
Hope it help.

how to set a new cookie without response object(express.js)

Before talking about issue, you need some background knowledge about my application.
I use node.js, express.js and mongoDB (with mongoose).
I was making a basic login function to do that I choose JWT for token and passport.js for authentication. and login flow is like below
Issue access token(expires in 10mins) and refresh token (expires in 2 weeks)
Store both token in cookies and store refresh token in DB too
Make a strategy for authentication.
Use strategy when you go to '/current' page.
Below is my code:
user.js:
router.post('/login', (req, res) => {
const { userid, password } = req.body;
// find email
User.findOne({ userid })
.then(user => {
if (!user) {
return res.json({
loginSuccess: false,
message: "Auth failed, ID not found"
});
}
// compare password
bcrypt.compare(password, user.password)
.then(isMatch => {
if (isMatch) {
const accessPayload = {
id: user.id,
userid: user.userid,
role: user.role
};
// console.log(accessPayload.id);
const refreshPayload = {
id: user.id
}
jwt.sign(accessPayload, JWT_ACCESS_SECRET, { expiresIn: JWT_ACCESS_EXPIRATION_TIME}, (err, token) => {
const accessToken = 'Bearer ' + token
const accessT = token
jwt.sign(refreshPayload, JWT_REFRESH_SECRET, { expiresIn: JWT_REFRESH_EXPIRATION_TIME }, (err, refreshT) => {
//note that maxAge is in milliseconds
res.cookie('accessToken', accessT, { httpOnly: true }) //secure: true
res.cookie('refreshToken', refreshT, { httpOnly: true })
res.json({
success: true,
refreshToken: 'Bearer ' + refreshT,
accessToken: accessToken
})
User.saveRefreshToken(refreshT)
//이거 모듈화 왜앙돼
});
});
} else {
return res.json({ loginSuccess: false, message: "Wrong password" });
}
});
});
});
router.get('/current',passport.authenticate('custom', { session: false }), (req, res) => {
res.json({
id: req.user.id,
userid: req.user.userid,
role: req.user.role
// id: req.user.id,
});
})'
and my strategy(custom) is like below
require('dotenv').config();
const { auth } = require('../middleware/auth');
const { append } = require('express/lib/response');
const JwtStrategy = require('passport-jwt').Strategy;
const ExtractJwt = require('passport-jwt').ExtractJwt;
const passportCustom = require('passport-custom');
const CustomStrategy = passportCustom.Strategy;
// const res = require('express/lib/response');
const jwt = require('jsonwebtoken');
const mongoose = require('mongoose');
const User = mongoose.model('User');
const { verifyToken } = require('../utils/jwt');
module.exports = custom => {
custom.use('custom', new CustomStrategy(
function (req, done) {
const accessToken = req.cookies['accessToken'];
const refreshToken = req.cookies['refreshToken'];
//when both token are valid
if (
req && verifyToken('access', accessToken)
&& verifyToken('refresh', refreshToken)
) {
const verifyAccessToken = verifyToken('access', accessToken);
const user = {
id: verifyAccessToken.id,
userid: verifyAccessToken.userid,
role: verifyAccessToken.role
};
console.log(user)
return done(null, user);
}
// when refresh token is valid but access token expired
else if (
req && !verifyToken('access', accessToken)
&& verifyToken('refresh', refreshToken)
) {
console.log('you need new access token')
const refreshTokenInfo = verifyToken('refresh', refreshToken);
User.findById({ _id: refreshTokenInfo.id }, (err, user) => {
const Payload = {
id: user.id,
userid: user.userid,
role: user.role
}
console.log('old access token : ' +req.cookies['accessToken'])
jwt.sign(Payload, JWT_ACCESS_SECRET, { expiresIn: JWT_ACCESS_EXPIRATION_TIME }, (err, accessToken) => {
if (err) {
console.log(err)
}
console.log('new accesstoken : ' + accessToken)
});
return done(null, true)
})
return done(null, true)
}
}
))
}
The problem is at the case of ' // when refresh token is valid but access token expired'
When accessToken is expired but refresh one is valid I want to make new access token via information from DB(access DB when refresh token is correct) and set in cookie before done() However, I couldn't set cookie because there is no response object in parameter :/.
As far as I know, people use cookie to store access token and sometimes refresh it. I wonder how can I refresh my cookie in jwtStrategy and pass it to /current router so it recognize my refreshed access cookie
Thanks for reading, your help will be appreciated.

Passport.js Auth works on localhost but not on Heroku

I'm having a problem with my backend. Everything worked fine on localhost but after uploading to Heroku authorization stopped working.
The problem from what it looks like is a miscommunication between two scripts passport-setup.js and auth-routes.js.
passport-setup.js retrieves user information from an external database. This data is properly received in this script, here.
const passport = require('passport')
const { Strategy } = require('passport-twitter')
const keys = require('./keys')
const User = require('../models/user-model')
passport.serializeUser((user, done) => {
done(null, user.id)
})
passport.deserializeUser((id, done) => {
User.findById(id)
.then(user => done(null, user))
.catch(e => done(new Error('Failed to deserialize an user')))
})
passport.use(
new Strategy(
{
consumerKey: keys.TWITTER_CONSUMER_KEY,
consumerSecret: keys.TWITTER_CONSUMER_SECRET,
callbackURL: '/auth/twitter/redirect',
},
async (token, tokenSecret, profile, done) => {
const currentUser = await User.findOne({
twitterId: profile._json.id_str,
})
if (!currentUser) {
const newUser = await new User({
name: profile._json.name,
screenName: profile._json.screen_name,
twitterId: profile._json.id_str,
profileImageUrl: profile._json.profile_image_url,
token: token,
tokenSecret: tokenSecret,
}).save()
if (newUser) {
done(null, newUser)
}
}
done(null, currentUser)
}
)
)
But then it can't be received in the auth-routes.js script as req.user returns undefined in this case and the data can't be passed to the frontend.
const router = require('express').Router()
const passport = require('passport')
const fs = require('fs')
const MAIN_PAGE_URL = 'https://test.netlify.app'
const CLIENT_HOME_PAGE_URL = MAIN_PAGE_URL + '/createList'
router.get('/login/success', (req, res) => {
console.log(req.user, req.cookies)
if (req.user) {
const slots = JSON.parse(fs.readFileSync('./config/config.json')).slots
console.log(slots)
res.json({
success: true,
message: 'user has succesfully authenticated',
user: req.user,
slots: slots,
cookies: req.cookies,
})
}
})
router.get('/login/failed', (req, res) => {
res.status(401).json({
success: false,
message: 'user failed to authenticate',
})
//res.redirect(MAIN_PAGE_URL)
})
router.get('/logout', (req, res) => {
req.logout()
res.redirect(MAIN_PAGE_URL)
})
router.get('/twitter', passport.authenticate('twitter'))
router.get(
'/twitter/redirect',
passport.authenticate('twitter', {
successRedirect: CLIENT_HOME_PAGE_URL,
failureRedirect: '/auth/login/failed',
})
)
module.exports = { router, MAIN_PAGE_URL }

Setting cookie with JWT token works fine in postman, appears in devtools, but cannot get it in backend (Express)

The problem is that I cannot get the cookie in the server. It is set in the browser (I can see it in devtools). When using Postman it works fine (including the middleware). But for some reason when making the request from the browser to the middleware (authMiddleware) the token comes back undefined.
Anyone with any ideas would be great. I have been stuck on this for days! :O
App.js (server)
const express = require('express');
const cookieParser = require('cookie-parser');
const authRouter = require('./routes/authRoutes');
const cocktailRouter = require('./routes/cocktailRoutes');
require('dotenv').config();
const cors = require('cors');
const app = express();
mongoose.connect(process.env.DBURI, { useNewUrlParser: true, useUnifiedTopology: true, useCreateIndex: true })
.then((result) => {
console.log('listening');
app.listen(5000)
})
.catch((err) => console.log(err));
//middleware
app.use(express.static('public'));
app.use(express.json());
app.use(cookieParser());
app.use(cors({ origin: true, credentials: true }));
// ROUTER MIDDLEWARE
app.use('/api/cocktails', cocktailRouter);
app.use('/auth', authRouter);
authMiddleware
const User = require('../models/User');
require('dotenv').config();
//check user is authorized
const requireAuth = (req, res, next) => {
const token = req.cookies.jwt;
console.log('TOKEN', token)
//check json web token exists and is verified
if (token) {
jwt.verify(token, process.env.SECRET_KEY, (err, decodedToken) => {
if (err) {
// res.redirect('/auth/login');
console.log('not logged in')
} else {
console.log('logged in ')
next();
}
})
} else {
// res.redirect('/auth/login');
console.log('not logged in again')
}
};
module.exports = { requireAuth };
cocktailRoute
This is where I am implementing the requireAuth middleware:
const router = Router();
const { requireAuth } = require('../middleware/authMiddleware');
const { cocktail_get, cocktail_post, cocktail_put, cocktail_delete } = require('../controllers/cocktailController');
router.get('/', requireAuth, cocktail_get);
router.post('/', cocktail_post);
router.put('/:cocktailId', cocktail_put);
router.delete('/:cocktailId', cocktail_delete);
module.exports = router;
authController
const jwt = require('jsonwebtoken');
//handle errors function
const handleErrors = (err) => {
const { message } = err;
const errors = { email: '', password: '' }
//incorrect email
if (message === 'Incorrect email') {
errors.email = 'Invalid email';
};
//incorrect password
if (message === 'Incorrect password') {
errors.password = 'Invalid password';
};
//duplicate error = 11000
if (err.code === 11000) {
errors.email = 'That email is already registered';
return errors;
}
//validation errors
if (message.includes('user validation failed')) {
Object.values(err.errors).forEach(({ properties }) => {
errors[properties.path] = properties.message;
})
};
return errors;
}
//create jwt token
const maxAge = 3 * 24 * 60 * 60; // 3 days in seconds
const createToken = (id) => {
return jwt.sign({ id }, process.env.SECRET_KEY, { expiresIn: maxAge })
};
module.exports.register_post = async (req, res) => {
const { name, email, password } = req.body;
try {
const user = await User.create({ name, email, password });
const token = createToken(user._id);
res.cookie('jwt', token, { httpOnly: false, maxAge: maxAge * 1000 });
res.status(201).json({ user: user._id, token });
} catch (err) {
const errors = handleErrors(err);
res.status(400).json({ errors });
}
};
module.exports.login_post = async (req, res) => {
const { email, password } = req.body;
try {
const user = await User.login(email, password);
const token = createToken(user._id);
res.cookie('jwt', token, { httpOnly: false, maxAge: maxAge * 1000, secure: false });
res.status(200).json({ user: user._id });
} catch (err) {
const errors = handleErrors(err);
res.status(400).json({ errors });
}
};
module.exports.logout_get = (req, res) => {
console.log(res.cookie('jwt', '', { maxAge: 1 }))
res.cookie('jwt', '', { maxAge: 1 });
res.redirect('/');
}
FRONTEND (React)
LoginPage
const LoginPage = () => {
const [values, setValues] = useState({ email: '', password: '' });
const handleChange = (event) => {
const { name, value } = event.target;
setValues({ ...values, [name]: value });
};
const handleLoginFormSubmit = (event) => {
event.preventDefault();
const { email, password } = values;
try {
fetch(`${process.env.REACT_APP_API_URL}/auth/login`, {
method: "POST",
withCredentials: true,
credentials: 'include',
headers: { "Content-Type": "application/json", "Accept": "application/json" },
body: JSON.stringify({
email, password
})
})
} catch (err) { if (err.request) { console.log('REQUEST', err.request) } if (err.response) { console.log('RESPONSE', err.response) } }
};
return (
<div>
<h1>Login</h1>
<form onSubmit={handleLoginFormSubmit}>
<input type="text" value={values.email} name="email" placeholder="Enter your email" onChange={handleChange} />
<input type="password" value={values.password} name="password" placeholder="Enter your password" onChange={handleChange} />
<button>Login</button>
</form>
</div>
)
}
export default LoginPage

front end react is not sending data to to mongoDB database

THE app is suppose to register the new user and send the new users info to the MongoDB, but when i attempt to register the user it throws an error of 500 internal error. the console says the error is in the user file, the terminal say this is the error, Proxy error: Could not proxy request /api/users from localhost:3000 to https://localhost:5000.
[1] See https://nodejs.org/api/errors.html#errors_common_system_errors for more information (EPROTO).
I've already tried changing the proxy in the packet.json by giving it a different path and target but its not working. maybe i'm overlooking something. enter code here
import React, { useReducer } from 'react';
import axios from 'axios';
import AuthContext from './authContext';
import authReducer from './authReducer';
import {
REGISTER_SUCCESS,
REGISTER_FAIL,
USER_LOADED,
AUTH_ERROR,
LOGIN_SUCCESS,
LOGIN_FAIL,
LOGOUT,
CLEAR_ERRORS
} from '../types';
const AuthState = props => {
//initial state
const initialState = {
token: localStorage.getItem('token'),
isAuthenticated: null,
user: null,
loading: true,
error: null
};
const [ state, dispatch ] = useReducer(authReducer, initialState);
// load user
const loadUser = () => console.log('load user') ;
// register user
const register = async formData => {
const config = {
headers: {
'Content-Type': 'application/json'
}
}
try {
const res = await axios.post('api/users', formData, config);
dispatch({
type: REGISTER_SUCCESS,
payload: res.data
});
} catch (err){
dispatch({
type: REGISTER_FAIL,
payload: err.response.data.msg
});
}
}
// login user
const login = () => console.log('login') ;
//logut
const logout = () => console.log('logout') ;
// clear errors
const clearErrors = () => console.log('clearErrors') ;
return (
<AuthContext.Provider
value= {{
token: state.token,
isAuthenticated: state.isAuthenticated,
loading: state.loading,
user: state.user,
error: state.error,
register,
loadUser,
login,
logout,
clearErrors
}}>
{props.children}
</AuthContext.Provider>
);
};
export default AuthState;
//this is my server.js file with the routes
const express = require('express');
const connectDB = require('./config/db')
//connect MongoDB
connectDB();
const app = express();
//init middleware
app.use(express.json({extended: false}));
app.get('/', (req, res) => res.json({ msg: 'hello welcome'})
);
//define routes
app.use('/api/users', require('./routes/users'));
app.use('/api/auth', require('./routes/auth'));
app.use('/api/contacts', require('./routes/contacts'))
const PORT = process.env.PORT || 5000;
app.listen(PORT, () => console.log(`server is working on ${PORT}`))
// this is mongoDB code
const mongoose = require('mongoose');
const config = require('config');
const db = config.get('mongoURI');
const connectDB = async () =>{
try{ await
mongoose.connect(db, {
useNewUrlParser: true,
useCreateIndex: true,
useFindAndModify: false
});
console.log('mongo connected..')
} catch (err){
console.log(err.message);
process.exit(1)
}
};
module.exports = connectDB;
// this the users file where the console is throwing the 500 internal error.
const express = require('express');
const router = express.Router();
const bcrypt = require('bcryptjs');
const jwt = require('jsonwebtoken');
const config = require('config');
const { check, validationResult } = require('express-validator');
const User = require('../models/User')
// This route Post request to api/users,
// description register a user,
// access to public to register an become a user
router.post('/', [
check('name', 'Name is require').not().isEmpty(),
check('email', 'please include email').isEmail(),
check('password', 'enter a password with atleast 6 characters'
).isLength({min: 6})
],
async (req, res) =>{
const errors = validationResult(req);
if(!errors.isEmpty()){
return res.status(400).json({ errors: errors.array()});
}
const { name, email, password } = req.body;
try{
let user = await User.findOne({email});
if(user){
return res.status(400).json({msg: 'user already exist'})
}
user = new User({
name,
email,
password
});
const salt = await bcrypt.genSalt(10);
user.password = await bcrypt.hash(password, salt);
await user.save();
// object to send in the token
const payload = {
user: {
id: user.id
}
}
jwt.sign(payload, config.get('jwtSecret'), {
expiresIn: 36000
}, (err, token) => {
if(err) throw err;
res.json({token});
});
} catch (err){
console.log(err.message);
res.status(500).send('server error')
}
});
module.exports = router;
I figure out the problem!!!
I had an unexpected token in my users file that simple colon was interfering with the code

Categories

Resources