【问题标题】:How can I logout user on route change once JWT token is expired?JWT 令牌过期后,如何在路由更改时注销用户?
【发布时间】:2022-01-25 08:06:15
【问题描述】:

我正在使用 Passport JWT,如果它已经过期,我想检查 JWT 令牌的有效性以执行注销。我已经让它在页面刷新时起作用,但在路线更改时不起作用(例如,从导航栏)。每次重新渲染 any 路由组件时,我都需要找到一种方法来检查它,而且我知道我很可能不需要对每个组件都执行此操作。我只是不知道如何

这是用于刷新页面的代码:

快递

authenticated.js

router.route("/").get((req, res) => {
  passport.authenticate("jwt", { session: false }, (err, user, info) => {
    if (!user) {
      res.status(401);
      res.send("Unauthorized")
    }
  })(req, res);
});

module.exports = router;

反应

AuthContext.js

export const AuthContext = createContext();

function AuthProvider({ children }) {
  const [isLoaded, setIsLoaded] = usePersistedState(false, "loaded");
  const [user, setUser] = usePersistedState(null, "username");
  const [isAuthenticated, setIsAuthenticated] = usePersistedState(
    false,
    "auth"
  );

  useEffect(() => {
    axios
      .get("/authenticated")
      .then((response) => {
        return;
      })
      .catch((error) => {
        setUser("");
        setIsAuthenticated(false);
        setIsLoaded(true);
      });
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, []);

  return (
    <div>
      {!isLoaded ? (
        <h3>Loading...</h3>
      ) : (
        <AuthContext.Provider
          value={{ user, setUser, isAuthenticated, setIsAuthenticated }}
        >
          {children}
        </AuthContext.Provider>
      )}
    </div>
  );
}

export default AuthProvider;

index.js

ReactDOM.render(
  <AuthProvider>
    <App />
  </AuthProvider>,
  document.getElementById("root")
);

更新

我试图通过在我的 PrivateOutlet.js 上添加这个 useEffect 函数来完成它,它处理私有路由,但它没有工作:

function PrivateOutlet() {
  const authContext = useContext(AuthContext);

  const location = useLocation();

  useEffect(() => {
    axios
      .get("/authenticated")
      .then((response) => {
        return;
      })
      .catch((err) => {
        authContext.setIsAuthenticated(false);
        authContext.setUser("");
      });
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [location]);

  return authContext.isAuthenticated ? (
    <Outlet />
  ) : (
    <Navigate to="/login" replace state={{ path: location.pathname }} />
  );
}

export default PrivateOutlet;

【问题讨论】:

    标签: node.js reactjs authentication routes jwt


    【解决方案1】:

    响应不特定于任何平台/语言。通常,身份验证提供程序/服务正在向客户端颁发令牌。用于在资源服务器验证后访问私有资源的令牌。当您使用JWT token 时,资源服务器/服务可以在不与身份验证服务对话或不执行数据库查找的情况下验证令牌。您的服务器端代码始终需要使用传入请求验证令牌,您可以通过为受保护的请求创建拦截器来做到这一点。简而言之,您可以在需要时调用来自客户端的调用来验证令牌。

    【讨论】:

    • 我已经编辑了原始问题,因为我在这方面取得了一些进展,也使它更客观。
    【解决方案2】:

    它可能是通过包装器组件进行检查的套接字调用。如果socket返回false,那么history.push他进入不需要登录的页面

    【讨论】:

      【解决方案3】:

      原始问题的“更新”部分中列出的方法是正确的,但是我的代码有一些警告使其无法正常工作。

      在将AuthContext.js 移至PrivateOutlet.js 后,我忘记将useEffect()AuthContext.js 中删除,我还修改了依赖数组以包含location.pathname 而不仅仅是location

      PrivateOutlet.js

      function PrivateOutlet() {
        const authContext = useContext(AuthContext);
      
        const location = useLocation();
      
        useEffect(() => {
          axios
            .get("/authenticated")
            .then((response) => {
              return;
            })
            .catch((err) => {
              authContext.setIsAuthenticated(false);
              authContext.setUser("");
            });
          // eslint-disable-next-line react-hooks/exhaustive-deps
        }, [location.pathname]);
      
        return authContext.isAuthenticated ? (
          <Outlet />
        ) : (
          <Navigate to="/login" replace state={{ path: location.pathname }} />
        );
      }
      
      export default PrivateOutlet;
      

      这是一个小改动,可能根本不会影响任何事情,但在我的 Express 服务器上的 authenticated.js 中,我刚刚从使用自定义回调返回到标准 Passport 回调,允许它通过以下方式处理未经授权的调用本身:

      authenticated.js

      router
        .route("/")
        .get(passport.authenticate("jwt", { session: false }), (req, res) => {
          //do some stuff
          res.json();
        });
      
      module.exports = router;
      

      【讨论】:

        猜你喜欢
        • 2020-02-20
        • 2016-10-23
        • 2019-09-24
        • 2018-07-30
        • 2020-09-11
        • 2019-07-20
        • 2018-03-30
        • 2019-04-18
        • 2018-09-10
        相关资源
        最近更新 更多