首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如果令牌验证失败,Remix.run,Remix-Auth销毁用户会话

如果令牌验证失败,Remix.run,Remix-Auth销毁用户会话
EN

Stack Overflow用户
提问于 2022-09-21 04:19:07
回答 1查看 157关注 0票数 0

我正在使用Remix,以及Remix,并使用Twitch /OAuth,这要求我每隔一小时就签入他们的/validate端点文档。有人建议我使用资源路由,如果验证端点返回401的状态,则有人建议使用该路由,但是,正如我在请求需要每小时发送一次之前所说的那样,我想也许可以每小时向资源路由使用React-Query to POST之类的东西。

只是指出我使用createCookieSessionStorage与Remix一起创建会话

问题

我没有能够实现实际的会话被销毁和用户被重新路由到登录页面,我已经留下了什么实际的代码,我目前有任何帮助或建议,以实现实际的会话被销毁,如果验证失败将被重新路由到登录页面将不胜感激。

代码语言:javascript
复制
// React Query client side, checks if the users token is still valid
  const { error, data } = useQuery("TV-Revalidate", () =>
    fetch("https://id.twitch.tv/oauth2/validate", {
      headers: {
        Authorization: `Bearer ${user?.token}`,
      },
    }).then((res) => res.json())
  );

上面的React Query返回以下内容

代码语言:javascript
复制
// My attempt at the resource route
// ~routes/auth/destroy.server.ts
import { ActionFunction, redirect } from "@remix-run/node";
import { destroySession, getSession } from "~/services/session.server";

export const action: ActionFunction = async ({request}) => {
    const session = await getSession(request.headers.get("cookie"))
    return redirect("/login", {
        headers: {
            "Set-Cookie": await destroySession(session)
        }
    })
}
代码语言:javascript
复制
// Second attempt at resource route
// ~routes/auth/destroy.server.ts
import { ActionFunction, redirect } from "@remix-run/node";
import { destroySession, getSession } from "~/services/session.server";

export const action: ActionFunction = async ({request}) => {
    const session = await getSession(request.headers.get("cookie"))
    return destroySession(session)
}

我尝试使用if语句对资源路由使用POST,或者使用else呈现页面,但是,由于函数作为子函数无效,并且页面是空的,所以这肯定不会作为反应错误出现。

代码语言:javascript
复制
//index.tsx
export default function Index() {
  const { user, bits, vali } = useLoaderData();

  console.log("loader", vali);

  const { error, data } = useQuery("TV-Revalidate", () =>
    fetch("https://id.twitch.tv/oauth2/validate", {
      headers: {
        Authorization: `Bearer ${user?.token}`,
      },
    }).then((res) => res.json())
  );

  if (data?.status === 401)
    return async () => {
      await fetch("~/services/destroy.server", { method: "POST" });
    };
  else
    return ( ... );}
EN

回答 1

Stack Overflow用户

发布于 2022-11-15 21:17:46

你可以用里米克斯的useFetcher钩子。

https://remix.run/docs/en/v1/api/remix#usefetcher

代码语言:javascript
复制
// Resource route
// routes/api/validate
export const loader: LoaderFunction = async ({ request }) => {
    const session = await getSession(request);
    try {
        const { data } = await fetch("https://id.twitch.tv/oauth2/validate", {
            headers: {
                Authorization: `Bearer ${session.get("token")}`
            }
        });
        return json({
            data
        }, {
            headers: {
                "Set-Cookie": await commitSession(session),
            }
        });
        
    } catch(error) {
        return redirect("/login", {
            headers: {
                "Set-Cookie": await destroySession(session)
            }
        });
    }
}

然后在您的路由组件中,如下所示:

代码语言:javascript
复制
    const fetcher = useFetcher();
    
    useEffect(() => {
        if (fetcher.type === 'init') {
            fetcher.load('/api/validate');
        }
    }, [fetcher]);
    
    useEffect(() => {
        if(fetcher.data?.someValue {
            const timeout = setTimeout(() => fetcher.load('/api/validate'), 1 * 60 * 60 * 1000);
            return () => clearTimeout(timeout);
        }
    },[fetcher.data]);
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/73795309

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档