Next.js:在重定向到 Keycloak 登录页面之前阻止显示索引页面
Posted
技术标签:
【中文标题】Next.js:在重定向到 Keycloak 登录页面之前阻止显示索引页面【英文标题】:Next.js: prevent Showing index page before redirecting to Keycloak Login page 【发布时间】:2021-07-30 09:45:04 【问题描述】:我一直在研究 Next.js 项目,该项目使用 Keycloak 进行身份验证。
我使用 '@react-keycloak/s-s-r' 库来实现前端身份验证。
这是我的 _app.js 代码(代码参考:https://github.com/react-keycloak/react-keycloak-examples/tree/master/examples/nextjs-app)
import cookie from 'cookie'
import * as React from 'react'
import type IncomingMessage from 'http'
import type AppProps, AppContext from 'next/app'
import s-s-rKeycloakProvider, s-s-rCookies from '@react-keycloak/s-s-r'
const keycloakCfg =
url: 'http://myauthurl/auth',
realm: 'myrealm',
clientId: 'myclientid',
interface InitialProps
cookies: unknown
function MyApp( Component, pageProps, cookies : AppProps & InitialProps)
const initOptions =
onLoad: 'login-required',
checkLoginIframe: false
return (
<s-s-rKeycloakProvider
keycloakConfig=keycloakCfg
persistor=s-s-rCookies(cookies)
initOptions=initOptions
>
<Component ...pageProps />
</s-s-rKeycloakProvider>
)
function parseCookies(req?: IncomingMessage)
if (!req || !req.headers)
return
return cookie.parse(req.headers.cookie || '')
MyApp.getInitialProps = async (context: AppContext) =>
// Extract cookies from AppContext
return
cookies: parseCookies(context?.ctx?.req),
export default MyApp
我的目标是将未经身份验证的用户重定向到 keycloak 登录页面。它通过添加“initOptions”来工作。但是,在重定向之前,应用程序会显示一秒钟的索引页面。
编辑: 在编写代码检查身份验证状态后,我设法为未登录的用户隐藏了组件。但是,登录成功后应用程序显示空白页面并且 keycloak 未定义。
import type AppProps, AppContext from "next/app";
import s-s-rKeycloakProvider, useKeycloak from "@react-keycloak/s-s-r";
import Provider from "urql";
import
keycloakConfig,
initOptions,
getPersistor,
Keycloak,
from "../libs/keycloak";
import parseCookies from "../libs/cookie";
import useMemo from "react";
import createUrqlClient, s-s-rCache from "../libs/urql";
interface Props extends AppProps
cookies: unknown;
token?: string;
function MyApp( Component, pageProps, cookies, token : Props)
const urqlClient = useMemo(() => createUrqlClient(token), [token]);
const keycloak = useKeycloak
console.log(keycloak) //undefined after login success
console.log(keycloak?.authenticated ) //undefined after login success
// s-s-r cache for urql
if (pageProps?.urqlState)
s-s-rCache.restoreData(pageProps.urqlState);
return (
<s-s-rKeycloakProvider
keycloakConfig=keycloakConfig
persistor=getPersistor(cookies)
initOptions=initOptions
>
<Provider value=urqlClient>
keycloak?.authenticated && <Component ...pageProps />
</Provider>
</s-s-rKeycloakProvider>
);
MyApp.getInitialProps = async (context: AppContext) =>
const keycloak = Keycloak(context?.ctx?.req);
return
cookies: parseCookies(context?.ctx?.req),
token: keycloak.token,
;
;
export default MyApp;
【问题讨论】:
它必须等待几秒钟,因为它需要检查身份验证.. 你想要的行为是什么? @Someone 特别感谢您的回答!我希望的行为是如果用户输入 url (localhost:3000) -> 检查身份验证 -> 如果未登录则重定向到 keycloak 登录页面。正如我在问题中所说,重定向是可以的,但在显示登录页面索引页面之前稍微暴露。 身份验证检查是异步的,您需要时间检查。看看下面的答案。您可以替代使用keycloak?.authenticated ? <CustomComponent /> : null
,这样它就不会显示任何内容
@Someone special 谢谢你的建议!我不想在身份验证之前显示任何页面,所以我尝试使用 keycloak?.authenticated ? :空。虽然 keycloak 是通过调用 useKeycloak() 声明的,但 keycloak 是未定义的。
您需要根据我正确提供的代码检查您的代码。这是因为keycloak?.authenticated
不会返回未定义的错误,因为它使用了可选链接 - developer.mozilla.org/en-US/docs/Web/javascript/Reference/…
【参考方案1】:
它必须等待几秒钟,因为它需要检查身份验证..您希望的行为是什么?
您可以在页面中使用useKeycloak
挂钩来显示您想要的行为(例如重定向到登录页面......)
const IndexPage = () =>
const keycloak = useKeycloak<KeycloakInstance>()
const loggedinState = keycloak?.authenticated ? (
<span className="text-success">logged in</span>
) : (
<span className="text-danger">NOT logged in</span>
)
const welcomeMessage =
keycloak?.authenticated
? `Welcome back!`
: 'Welcome visitor. Please login to continue.'
return (
<Layout title="Home | Next.js + TypeScript Example">
<h1 className="mt-5">Hello Next.js + Keycloak ?</h1>
<div className="mb-5 lead text-muted">
This is an example of a Next.js site using Keycloak.
</div>
<p>You are: loggedinState</p>
<p>welcomeMessage</p>
</Layout>
)
export default IndexPage
来自https://github.com/react-keycloak/react-keycloak-examples/blob/master/examples/nextjs-app/pages/index.tsx的简化示例
【讨论】:
以上是关于Next.js:在重定向到 Keycloak 登录页面之前阻止显示索引页面的主要内容,如果未能解决你的问题,请参考以下文章
Next.js:在实现私有路由时,如何在重定向之前防止未经授权的路由/页面的闪烁?
根据角色将不同的用户重定向到 Keycloak 登录的不同页面