useAuthContext在与后端通信时失败

huangapple go评论74阅读模式
英文:

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(&#39;./routes/auth&#39;);
const userRoutes = require(&#39;./routes/user&#39;);
const express = require(&#39;express&#39;);
const cors = require(&quot;cors&quot;);
const dotenv = require(&quot;dotenv&quot;);
dotenv.config();
const app = express();
const PORT = process.env.PORT || 3000
app.use(cors());
app.use(express.urlencoded({ extended: true }))
app.get(&#39;/&#39;, (req, res) =&gt; {
res.send(&#39;Testing&#39;)
})
app.use(&#39;/auth&#39;, authRoutes);
app.use(&#39;/user&#39;, userRoutes);
app.listen(PORT, () =&gt; {
console.log(&quot;app is running!&quot;)
});

user.js (routes)

const { PrismaClient } = require(&#39;@prisma/client&#39;)
const express = require(&quot;express&quot;);
const router = express.Router();
const prisma = new PrismaClient();
router.get(&#39;/user/me&#39;, async (req, res) =&gt; {
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 &quot;react&quot;;
import { useEffect } from &quot;react&quot;;
import axios from &quot;../config/axios&quot;;
const AuthContext = createContext()
const authReducer = (state, action) =&gt; {
switch(action.type) {
case &#39;LOGIN&#39;: 
return { user: action.payload }
case &#39;LOGOUT&#39;:
return { user: null }
default:
return state
}
}
const AuthContextProvider = ({ children }) =&gt; {
const [state, dispatch] = useReducer(authReducer, {
user: null
})
useEffect(() =&gt; {
const user = localStorage.getItem(&#39;token&#39;)
if (user) {
dispatch({ type: &#39;LOGIN&#39;, payload: user })
}
}, [])
const getUserInfo = async () =&gt; {
const token = localStorage.getItem(&#39;token&#39;);
if (token) {
try {
const res = await axios.get(`/user/me`, {
headers: {
&#39;x-auth-token&#39;: token,
},
});
console.log(res.data.user);
dispatch({
type: &#39;LOGIN&#39;,
payload: {
user: res.data.user,
},
});
} catch (err) {
console.error(err);
}
} else {
delete axios.defaults.headers.common[&#39;x-auth-token&#39;];
}
};
useEffect(() =&gt; {
const verifyUser = async () =&gt; {
if (!state.user) {
await getUserInfo();
}
};
verifyUser();
}, []);
const register = async (registerData) =&gt; {
try {
const response = await axios.post(&quot;/register&quot;, registerData);
return response.data;
} catch (error) {
if (!error.response) {
return { status: &quot;ERRROR&quot;, message: &quot;No Server Response&quot; };
} 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) =&gt; {
try {
const response = await axios.post(&quot;/login&quot;, loginData);
localStorage.setItem(&quot;token&quot;, response.data.token);
await getUserInfo();
return response.data;
} catch (error) {
if (!error.response) {
return { type: &quot;ERROR&quot;, message: &quot;No Server Response&quot; };
} 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 () =&gt; {
try {
localStorage.removeItem(&quot;token&quot;);
dispatch({
type: &quot;LOGOUT&quot;,
});
} catch (error) {
console.log(error.response);
}
};
return (
&lt;AuthContext.Provider value={{ ...state, dispatch, register, login, logout }}&gt;
{ children }
&lt;/AuthContext.Provider&gt;
)
}
export {AuthContext, authReducer, AuthContextProvider}

答案1

得分: 1

请不要在 authRoutesuserRoutes 中重新声明根路由名称。根据当前的形式,您需要这样调用它:

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(&#39;/me&#39;, cb)

then, you'll be able to call it properly

await axios.get(`/user/me`, cb)

You can read more in express.js documentation.

huangapple
  • 本文由 发表于 2023年5月29日 16:44:30
  • 转载请务必保留本文链接:https://go.coder-hub.com/76355853.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定