I have a problem. I need to login in Keycloak, but i don't want to use default pages from Keycloak. I have pages for "sign-in" and "sign-up". I wrote requests and can recieve access token for user, but what i should to do next? I use @react-keycloak/ssr and keycloak-js
This is _app.tsx
import './globals.css';
import '@fortawesome/fontawesome-free/css/all.css'
import Head from 'next/head';
import { Header } from "../shared/components/header/header";
import Footer from "../shared/components/footer/footer";
import cookie from 'cookie';
import type { IncomingMessage } from 'http';
import type { AppContext } from 'next/app';
import { SSRKeycloakProvider, SSRCookies } from '@react-keycloak/ssr';
const keycloakCfg = {
url: `https://${process.env.AUTH_HOST}/auth`,
realm: 'myrealm',
clientId: 'react-client',
}
export default function MyApp({ Component, pageProps, cookies }) {
console.log(cookies);
const initOptions = {
onLoad: 'check-sso',
checkLoginIframe: false,
flow: 'implicit',
}
return (
<>
<Head>
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossOrigin="" />
<link
href="https://fonts.googleapis.com/css2?family=Open+Sans:wght@300;400;500;600;700;800&display=swap"
rel="stylesheet" />
<link rel="icon" type="image/png" href="/favicon.png" />
</Head>
<Header />
<SSRKeycloakProvider
keycloakConfig={keycloakCfg}
persistor={SSRCookies(cookies)}
initOptions={initOptions}
>
<Component {...pageProps} />
</SSRKeycloakProvider>
<Footer />
</>
);
}
function parseCookies(req?: IncomingMessage) {
if (!req || !req.headers) {
return {}
};
return cookie.parse(req.headers.cookie || '');
}
MyApp.getInitialProps = async (context: AppContext) => {
return {
cookies: parseCookies(context?.ctx?.req),
}
}
sign-in/index.tsx
import Form from '../../shared/components/form/form';
import styles from './sign-in.module.scss';
import Input from '../../shared/components/input/input';
import Checkbox from '../../shared/components/checkbox/checkbox';
import Button from '../../shared/components/button/button';
import React, { useEffect } from 'react';
import Head from 'next/head';
import { PAGE_TITLES } from '../../shared/constants/titles.const';
import BottomPanel from '../../shared/components/bottom-panel/bottom-panel';
import Link from 'next/link';
import { useKeycloak } from '@react-keycloak/ssr';
import { KeycloakInstance } from 'keycloak-js';
import { useRouter } from 'next/router';
import { getToken } from '../../shared/utils/keycloak-functions';
export default function SignIn() {
const links = [
{
text: 'News',
url: '/news'
},
{
text: 'Community',
url: '/news'
},
{
text: 'Development',
url: '/news'
}
];
// if user is authenticated rediretc to '/'
const router = useRouter();
const { keycloak } = useKeycloak<KeycloakInstance>();
useEffect(() => {
if (keycloak?.authenticated) router.push('/');
});
async function login() {
const tokens = await getToken();
if (tokens) {
console.log(tokens);
router.push('/');
}
}
return (
<>
<Head>
<title>{PAGE_TITLES.signIn}</title>
</Head>
<main className={styles.page}>
<Form>
<h2 className={styles.heading}>Sign in</h2>
<label className={styles.formRow}>
<span className={styles.label}>Email</span>
<Input name="username"/>
</label>
<label className={styles.formRow}>
<span className={styles.label}>Password</span>
<Input type="password" name="password"/>
</label>
<div className={styles.checkboxOuter}>
<Checkbox>Remember me</Checkbox>
</div>
<br />
<div className={styles.buttonOuter}>
<Button action={() => login() }>Login</Button>
</div>
<div className={styles.formFooter}>
<Link href="/sign-up">
<a>Register</a>
</Link>
</div>
</Form>
<BottomPanel links={links} />
</main>
</>
);
}
and this is a function getToken
export async function getToken() {
const tokenEndpoint = `https://localhost/auth/realms/myrealm/protocol/openid-connect/token`;
const fields = document.querySelectorAll('input');
const username = fields[1].value;
const password = fields[2].value;
const body = `client_id=${client_id}&username=${username}&password=${password}&grant_type=password&scope=openid`;
let token;
const res = await fetch(tokenEndpoint, {
method: "POST",
body: body,
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
}
}).then((response) => response.json())
.then((responseJSON) => {
token = responseJSON;
});
return token;
}
Can i somehow set access token to initOptions in SSRKeycloakProvider? When i login through default page, Keycloak redirects me to http://localhost:3000/ and everything is OK. I can see idToken and refreshToken. But when i recive accessToken, keycloak doesn't consider me authorized. Maybe i should to set some values in cookie? Help me, please. I'm tired of this task. Thanks