英文:
useAuthContext fails when communicating with backend
问题
I am building a full stack real estate app using reactJs, postgres, express & prisma.
当我想要检查本地存储中是否有令牌时,它失败并返回一个错误消息,显示404未找到。
我尝试搜索解释,但总是相同的情况,不适用于我的情况。
最终,我希望能够获取已登录用户的数据并在我的前端中使用它。如果有其他关于如何实现这一点的提示,请告诉我!
== API ==
Index.js
const authRoutes = require('./routes/auth');
const userRoutes = require('./routes/user');
const express = require('express');
const cors = require("cors");
const dotenv = require("dotenv");
dotenv.config();
const app = express();
const PORT = process.env.PORT || 3000
app.use(cors());
app.use(express.urlencoded({ extended: true }))
app.get('/', (req, res) => {
res.send('Testing')
})
app.use('/auth', authRoutes);
app.use('/user', userRoutes);
app.listen(PORT, () => {
console.log("app is running!")
});
user.js (routes)
const { PrismaClient } = require('@prisma/client')
const express = require("express");
const router = express.Router();
const prisma = new PrismaClient();
router.get('/user/me', async (req, res) => {
try {
const user = await prisma.user.findUnique({
where: { id: req.user.id },
});
console.log(user);
res.status(200).json({ user });
} catch (error) {
res.status(500).json(error);
}
});
module.exports = router;
== APP ==
Authcontext.js
import { createContext, useReducer } from "react";
import { useEffect } from "react";
import axios from "../config/axios";
const AuthContext = createContext()
const authReducer = (state, action) => {
switch(action.type) {
case 'LOGIN':
return { user: action.payload }
case 'LOGOUT':
return { user: null }
default:
return state
}
}
const AuthContextProvider = ({ children }) => {
const [state, dispatch] = useReducer(authReducer, {
user: null
})
useEffect(() => {
const user = localStorage.getItem('token')
if (user) {
dispatch({ type: 'LOGIN', payload: user })
}
}, [])
const getUserInfo = async () => {
const token = localStorage.getItem('token');
if (token) {
try {
const res = await axios.get(`/user/me`, {
headers: {
'x-auth-token': token,
},
});
console.log(res.data.user);
dispatch({
type: 'LOGIN',
payload: {
user: res.data.user,
},
});
} catch (err) {
console.error(err);
}
} else {
delete axios.defaults.headers.common['x-auth-token'];
}
};
useEffect(() => {
const verifyUser = async () => {
if (!state.user) {
await getUserInfo();
}
};
verifyUser();
}, []);
const register = async (registerData) => {
try {
const response = await axios.post("/register", registerData);
return response.data;
} catch (error) {
if (!error.response) {
return { status: "ERRROR", message: "No Server Response" };
} else if (error.response.status === 409) {
return error.response.data;
} else if (error.response.status === 400) {
return error.response.data;
} else {
return error.response.data;
}
}
};
const login = async (loginData) => {
try {
const response = await axios.post("/login", loginData);
localStorage.setItem("token", response.data.token);
await getUserInfo();
return response.data;
} catch (error) {
if (!error.response) {
return { type: "ERROR", message: "No Server Response" };
} else if (error.response.status === 400) {
return error.response.data;
} else if (error.response.status === 401) {
return error.response.data;
} else {
return error.response.data;
}
}
};
const logout = async () => {
try {
localStorage.removeItem("token");
dispatch({
type: "LOGOUT",
});
} catch (error) {
console.log(error.response);
}
};
return (
<AuthContext.Provider value={{ ...state, dispatch, register, login, logout }}>
{ children }
</AuthContext.Provider>
)
}
export {AuthContext, authReducer, AuthContextProvider}
英文:
I am building a full stack real estate app using reactJs, postgres, express & prisma.
When I want to check if there is a token stored in my localstorage, it fails and returns an error message giving a 404 not found.
I tried to search for explanation but it's always the same story and it doesn't work in my situation.
Eventually I want to be able to get the data from the logged in user and use it on my front end. If anyone has any additional tips on how to do this, please let me know!
== API ==
Index.js
const authRoutes = require('./routes/auth');
const userRoutes = require('./routes/user');
const express = require('express');
const cors = require("cors");
const dotenv = require("dotenv");
dotenv.config();
const app = express();
const PORT = process.env.PORT || 3000
app.use(cors());
app.use(express.urlencoded({ extended: true }))
app.get('/', (req, res) => {
res.send('Testing')
})
app.use('/auth', authRoutes);
app.use('/user', userRoutes);
app.listen(PORT, () => {
console.log("app is running!")
});
user.js (routes)
const { PrismaClient } = require('@prisma/client')
const express = require("express");
const router = express.Router();
const prisma = new PrismaClient();
router.get('/user/me', async (req, res) => {
try {
const user = await prisma.user.findUnique({
where: { id: req.user.id },
});
console.log(user);
res.status(200).json({ user });
} catch (error) {
res.status(500).json(error);
}
});
module.exports = router;
== APP ==
Authcontext.js
import { createContext, useReducer } from "react";
import { useEffect } from "react";
import axios from "../config/axios";
const AuthContext = createContext()
const authReducer = (state, action) => {
switch(action.type) {
case 'LOGIN':
return { user: action.payload }
case 'LOGOUT':
return { user: null }
default:
return state
}
}
const AuthContextProvider = ({ children }) => {
const [state, dispatch] = useReducer(authReducer, {
user: null
})
useEffect(() => {
const user = localStorage.getItem('token')
if (user) {
dispatch({ type: 'LOGIN', payload: user })
}
}, [])
const getUserInfo = async () => {
const token = localStorage.getItem('token');
if (token) {
try {
const res = await axios.get(`/user/me`, {
headers: {
'x-auth-token': token,
},
});
console.log(res.data.user);
dispatch({
type: 'LOGIN',
payload: {
user: res.data.user,
},
});
} catch (err) {
console.error(err);
}
} else {
delete axios.defaults.headers.common['x-auth-token'];
}
};
useEffect(() => {
const verifyUser = async () => {
if (!state.user) {
await getUserInfo();
}
};
verifyUser();
}, []);
const register = async (registerData) => {
try {
const response = await axios.post("/register", registerData);
return response.data;
} catch (error) {
if (!error.response) {
return { status: "ERRROR", message: "No Server Response" };
} else if (error.response.status === 409) {
return error.response.data;
} else if (error.response.status === 400) {
return error.response.data;
} else {
return error.response.data;
}
}
};
const login = async (loginData) => {
try {
const response = await axios.post("/login", loginData);
localStorage.setItem("token", response.data.token);
await getUserInfo();
return response.data;
} catch (error) {
if (!error.response) {
return { type: "ERROR", message: "No Server Response" };
} else if (error.response.status === 400) {
return error.response.data;
} else if (error.response.status === 401) {
return error.response.data;
} else {
return error.response.data;
}
}
};
const logout = async () => {
try {
localStorage.removeItem("token");
dispatch({
type: "LOGOUT",
});
} catch (error) {
console.log(error.response);
}
};
return (
<AuthContext.Provider value={{ ...state, dispatch, register, login, logout }}>
{ children }
</AuthContext.Provider>
)
}
export {AuthContext, authReducer, AuthContextProvider}
答案1
得分: 1
请不要在 authRoutes
和 userRoutes
中重新声明根路由名称。根据当前的形式,您需要这样调用它:
await axios.get(`/user/user/me`, cb)
相反,为了保持 axios 调用如当前所声明的那样,将路由声明如下:
router.get('/me', cb)
然后,您将能够正确调用它:
await axios.get(`/user/me`, cb)
您可以在 express.js 文档 中详细了解更多信息。
英文:
Please do not redeclare root route name in authRoutes
and userRoutes
. With current shape, you'd have to call it:
await axios.get(`/user/user/me`, cb)
Instead, to keep axios calls as they are declared now, declare routes as below:
router.get('/me', cb)
then, you'll be able to call it properly
await axios.get(`/user/me`, cb)
You can read more in express.js documentation.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论