Halboffizielles Beispiel
Die with-cookie-auth
Beispiele leiten weiter getInitialProps
. Ich bin nicht sicher, ob es sich um ein gültiges Muster handelt oder nicht, aber hier ist der Code:
Profile.getInitialProps = async ctx => {
const { token } = nextCookie(ctx)
const apiUrl = getHost(ctx.req) + '/api/profile'
const redirectOnError = () =>
typeof window !== 'undefined'
? Router.push('/login')
: ctx.res.writeHead(302, { Location: '/login' }).end()
try {
const response = await fetch(apiUrl, {
credentials: 'include',
headers: {
Authorization: JSON.stringify({ token }),
},
})
if (response.ok) {
const js = await response.json()
console.log('js', js)
return js
} else {
// https://github.com/developit/unfetch#caveats
return await redirectOnError()
}
} catch (error) {
// Implementation or Network error
return redirectOnError()
}
}
Es behandelt sowohl die Server- als auch die Client-Seite. Der fetch
Aufruf ist derjenige, der tatsächlich das Authentifizierungstoken erhält. Möglicherweise möchten Sie diesen in eine separate Funktion kapseln.
Was ich stattdessen raten würde
1. Weiterleiten beim serverseitigen Rendern (Flash während der SSR vermeiden)
Dies ist der häufigste Fall. Sie möchten an dieser Stelle umleiten, um zu vermeiden, dass die erste Seite beim ersten Laden blinkt.
MyApp.getInitialProps = async appContext => {
const currentUser = await getCurrentUser(); // define this beforehand
const appProps = await App.getInitialProps(appContext);
// check that we are in SSR mode (NOT static and NOT client-side)
if (typeof window === "undefined" && appContext.ctx.res.writeHead) {
if (!currentUser && !isPublicRoute(appContext.router.pathname)) {
appContext.ctx.res.writeHead(302, { Location: "/account/login" });
appContext.ctx.res.end();
}
}
return { ...appProps, currentUser };
};
2. Umleiten in componentDidMount (nützlich, wenn SSR deaktiviert ist, z. B. im statischen Modus)
Dies ist ein Fallback für das clientseitige Rendern.
componentDidMount() {
const { currentUser, router } = this.props;
if (!currentUser && !isPublicRoute(router.pathname)) {
Router.push("/account/login");
}
}
Ich konnte es nicht vermeiden, die erste Seite im statischen Modus zu flashen. Fügen Sie diesen Punkt hinzu, da Sie während des statischen Builds nicht umleiten können, aber es scheint besser zu sein als die üblichen Ansätze. Ich werde versuchen zu bearbeiten, wenn ich Fortschritte mache.
Das vollständige Beispiel finden Sie hier
Relevantes Problem, das leider nur von einem Kunden beantwortet wird