- When user signs in, you send the credentials to
pages/api/auth/login
. you check the verification and create a token.
I use cookies-next
library to deal with the cookies.
import { setCookie } from "cookies-next";
export default async function handler(req: NextApiRequest,res: NextApiResponse)
{
// pass all the checking
const token = await jwt.sign(credentials,secret)
setCookie("jwt", token, { req, res, maxAge: 60 * 60 * 24 });
}
- everytime you make a request, you attach the token to the header.
Using cookies-next
import { getCookie } from "cookies-next";
const jwt = getCookie("jwt");
const response = await axios.get(`${process.env.BASE/whatever}`, {
headers: {
Authorization: `Bearer ${jwt}`,
},
});
- Before in serverside functions, we could access to
req
object and check if the user is authenticated or not. To handle this in next.js I create an endpoint api/auth/me
. I sent a request to this endpoint to check if the user has a valid jwt or not. I have to do this in top-level component of the app directory. I created an Authentication Context and inside useEffect
I check the status of the user. I will keep track of the state:
in Authentication Context, client component
const fetchUser = async () => {
setAuthState({
data: null,
error: null,
loading: true,
});
try {
const jwt = getCookie("jwt");
if (!jwt) {
return setAuthState({
data: null,
error: null,
loading: false,
});
}
const response = await axios.get(`${process.env.BASE/api/auth/me}`, {
headers: {
Authorization: `Bearer ${jwt}`,
},
});
setAuthState({
data: response.data,
error: null,
loading: false,
});
} catch (error: any) {
setAuthState({
data: null,
error: error.response.data.errorMessage,
loading: false,
});
}
};
useEffect(() => {
fetchUser();
}, []);
- this is
pages/api/auth/me
endpoint.
I make a request here inside auth context
export default async function handler(req: NextApiRequest,res: NextApiResponse)
{
const bearerToken = req.headers["authorization"] as string;
const token = bearerToken.split(" ")[1];
const payload = jwt.decode(token) as { email: string };
if (!payload.email) {
return res.status(401).json({
errorMessage: "Unauthorized request",
});
}
const user = yourFetchUser(payload.email)
if (!user) {
return res.status(401).json({
errorMessage: "User not found",
});
}
return res.json({...user});
}
- check if the user is authenticated inside navbar.
this is a client component
const { data, loading } = useContext(AuthenticationContext);
Based on data you set conditionally display user name or sign in button.