I have a basic next.js application that does two things:
- provide an authentication mechanism using keycloak
- talk to a backend server that authorizes each request using the keycloak-access-token
I use the @react-keycloak/ssr library to achieve this. The problem now is that after I login and get redirected back to my application the cookie that contains the kcToken is empty. After I refresh my page it works like expected.
I understand that maybe my entire process flow is wrong. If so, what is the "usual" way to achieve what is mentioned above?
export async function getServerSideProps(context) {
const base64KcToken = context.req.cookies.kcToken // the cookie that keycloak places after login
const kcToken = base64KcToken ? Buffer.from(base64KcToken, "base64") : ""
// the backend server passes the token along to keycloak for role-based authorization
const res = await fetch(`${BACKEND_URL}/info`, {
headers: {
"Authorization": "Bearer " + kcToken
}
})
const data = await res.json()
// ... exception handling is left out for readability ...
return {
props: {
data
}
}
}
export default function Home({data}) {
const router = useRouter() // the next.js client side router to redirect to keycloak
const { keycloak, initialized } = useKeycloak() // keycloak instance configured in _app.js
if (keycloak && !initialized && keycloak.createLoginUrl) router.push(keycloak.createLoginUrl())
return (
<div> ... some jsx that displays data ... </div>
)
}
This process basically works but it feels really bad because a user that gets redirected after login is not able to see the fetched data unless he refreshes the entire page. This is because when getServerSideProps() is called right after redirect the base64KcToken is not there yet.
Also everything related to the login-status (eg. logout button) only gets displayed after ~1sec, when the cookie is loaded by the react-keycloak library.