My NextJs application is using app router. I am currently building an admin application and i want to clear the cookie when tab close is detected. How can i achieve that? I am new to nextjs and it is using cookie to authenticate. I am using axios to fetch my external backend server. The accessToken from my backend api gets expired in 1hr and i have set the MAX_AGE of the jwt session token to 1hr. I also want to logout automatically when the token expires. how can achieve this all?
我的NextJs应用程序正在使用应用程序路由器。我目前正在构建一个管理应用程序,我想在检测到选项卡关闭时清除Cookie。我怎样才能做到这一点呢?我对nextjs还不熟悉,它正在使用cookie进行身份验证。我正在使用AXIOS获取我的外部后端服务器。来自后端API的accesToken将在1小时后过期,并且我已将JWT会话令牌的MAX_AGE设置为1小时。我还想在令牌到期时自动注销。如何才能实现这一切呢?
This is how my layout.tsx file looks like
这是我的layout.tsx文件的外观
import React, { FC } from "react";
import ThemeRegistry from "@/theme/ThemeRegistry";
import { Poppins } from "next/font/google";
import ReduxProvider from "@/store/provider/ReduxProvider";
import "./globals.css";
import AuthProvider from "@/context/AuthProvider";
const poppins = Poppins({ subsets: ["latin"], weight: "400" });
interface LayoutProps {
children: React.ReactNode;
types: string;
}
export const metadata = {
title: "VastuVilla",
description: "Comprehensive Household Services",
};
const RootLayout: FC<LayoutProps> = async ({ children, types }) => {
return (
<html lang="en" className="bg-white">
<AuthProvider>
<ReduxProvider>
<ThemeRegistry>
<body className={poppins.className}>{children}</body>
</ThemeRegistry>
</ReduxProvider>
</AuthProvider>
</html>
);
};
export default RootLayout;
and this is my page.tsx file
这是我的Page.tsx文件
import React from "react";
import { NextPage } from "next";
import { redirect } from "next/navigation";
import { getServerSession } from "next-auth/next";
import { options } from "./api/auth/[...nextauth]/options";
const Home: NextPage = async () => {
const session = await getServerSession(options);
if (!session) {
redirect("/login");
}
return (
<main className="main" data-testid="home-component">
Hello
</main>
);
};
export default Home;
this is my middleware.ts file
这是我的midleware.ts文件
import { NextRequest, NextResponse } from "next/server";
import { getErrorResponse } from "./lib/helpers";
let redirectToLogin = false;
export async function middleware(req: NextRequest) {
let token: string | undefined;
if (req.cookies.has("next-auth.session-token")) {
token = req.cookies.get("next-auth.session-token")?.value;
} else if (req.headers.get("Authorization")?.startsWith("Bearer ")) {
token = req.headers.get("Authorization")?.substring(7);
}
if (req.nextUrl.pathname.startsWith("/login") && (!token || redirectToLogin))
return;
if (req.nextUrl.pathname.startsWith("/signup") && (!token || redirectToLogin))
return;
if (
!token &&
(req.nextUrl.pathname.startsWith("/api/users") ||
req.nextUrl.pathname.startsWith("/api/auth/logout"))
) {
return getErrorResponse(
401,
"You are not logged in. Please provide a token to gain access."
);
}
const response = NextResponse.next();
if (!token) {
return NextResponse.redirect(new URL(`/login`, req.url));
}
if (req.url.includes("/login") && token) {
return NextResponse.redirect(new URL("/", req.url));
}
if (req.url.includes("/signup") && token) {
return NextResponse.redirect(new URL("/", req.url));
}
return response;
}
export const config = {
matcher: [
"/profile",
"/login",
"/signup",
"/api/users/:path*",
"/api/auth/logout",
],
};
and this is my api to authenticate
这是我用于身份验证的API
import { __RUNTIME_CONFIG__ } from "@/config";
import { __REACT_APP_AUTHENTICATION__ } from "@/config/apiConfig";
import axiosInstance from "@/services/axiosFactory/axiosInstance";
import type { NextAuthOptions } from "next-auth";
import CredentialsProvider from "next-auth/providers/credentials";
import FacebookProvider from "next-auth/providers/facebook";
import GoogleProvider from "next-auth/providers/google";
export const options: NextAuthOptions = {
pages: {
signIn: "/login",
},
session: {
strategy: "jwt",
maxAge: 1 * 60 * 60,
},
providers: [
FacebookProvider({
clientId: __RUNTIME_CONFIG__.FACEBOOK_ID as string,
clientSecret: __RUNTIME_CONFIG__.FACEBOOK_SECRET as string,
}),
GoogleProvider({
clientId: __RUNTIME_CONFIG__.GOOGLE_CLIENT_ID as string,
clientSecret: __RUNTIME_CONFIG__.GOOGLE_CLIENT_SECRET as string,
}),
CredentialsProvider({
name: "Credentials",
credentials: {
username: {
label: "Username:",
type: "text",
placeholder: "your-cool-username",
},
password: {
label: "Password:",
type: "password",
placeholder: "your-awesome-password",
},
email: {
label: "Email:",
type: "email",
placeholder: "your-email",
},
},
async authorize(credentials) {
const response = await axiosInstance.post(
__REACT_APP_AUTHENTICATION__.AUTHENTICATE_SERVICE,
{
email: credentials?.email,
loginName: credentials?.username || "",
password: credentials?.password,
}
);
const user = response.data;
if (user) {
axiosInstance.defaults.headers.common["Authorization"] =
"Bearer " + user.accessToken;
return user;
} else {
return null;
}
},
}),
],
callbacks: {
async jwt({ token, user, session }) {
if (user) {
return {
...token,
...user,
};
}
return token;
},
async session({ session, token, user }) {
return {
...session,
user: {
...session.user,
accessToken: token.accessToken,
iat: token.iat,
exp: token.exp,
jti: token.jti,
},
};
},
},
secret: __RUNTIME_CONFIG__.NEXTAUTH_SECRET,
debug: process.env.NODE_ENV === "development",
};
更多回答
我是一名优秀的程序员,十分优秀!