Nimble Pixie Merchant

    @react-keycloak/ssr
    TypeScript icon, indicating that this package has built-in type declarations

    3.3.0 • Public • Published

    React Keycloak

    React Keycloak

    SSR bindings for Keycloak

    NPM (scoped)

    License lerna GitHub contributors Github Issues

    Gitter


    Table of Contents


    Install

    React Keycloak requires:

    • React 16.8 or later
    • keycloak-js 9.0.2 or later
    yarn add @react-keycloak/ssr

    or

    npm install --save @react-keycloak/ssr

    Getting Started

    This module has been created to support NextJS and Razzle, other SSR frameworks might be working as well.

    Setup

    Follow the guide related to your SSR Framework and note that SSRKeycloakProvider also accepts all the properties of KeycloakProvider.

    NextJS

    Requires NextJS 9 or later

    Create the _app.tsx file under pages folder and wrap your App inside SSRKeycloakProvider component and pass keycloakConfig and a TokenPersistor.

    Note: @react-keycloak/ssr provides a default TokenPersistor which works with cookies (exported as ServerPersistors.SSRCookies).

    The following examples will be based on that.

    import cookie from 'cookie'
    import * as React from 'react'
    import type { IncomingMessage } from 'http'
    import type { AppProps, AppContext } from 'next/app'
    
    import { SSRKeycloakProvider, SSRCookies } from '@react-keycloak/ssr';
    
    const keycloakCfg = {
      realm: '',
      url: '',
      clientId: ''
    }
    
    interface InitialProps {
      cookies: unknown
    }
    
    function MyApp({ Component, pageProps, cookies }: AppProps & InitialProps) {
      return (
        <SSRKeycloakProvider
          keycloakConfig={keycloakCfg}
          persistor={SSRCookies(cookies)}
        >
          <Component {...pageProps} />
        </SSRKeycloakProvider>
      )
    }
    
    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

    Razzle

    Requires Razzle 3 or later

    N.B: This setup requires you to install cookie-parser middleware.

    Edit your app server.js as follow

    ...
    
    import { ExpressCookies, SSRKeycloakProvider } from '@react-keycloak/ssr'
    
    // Create a function to retrieve Keycloak configuration parameters -- 'see examples/razzle-app'
    import { getKeycloakConfig } from './utils'
    
    const assets = require(process.env.RAZZLE_ASSETS_MANIFEST)
    
    const server = express()
    server
      .disable('x-powered-by')
      .use(express.static(process.env.RAZZLE_PUBLIC_DIR))
      .use(cookieParser()) // 1. Add cookieParser Express middleware
      .get('/*', (req, res) => {
        const context = {}
    
        // 2. Create an instance of ExpressCookies passing the current request
        const cookiePersistor = ExpressCookies(req)
    
        // 3. Wrap the App inside SSRKeycloakProvider
        const markup = renderToString(
          <SSRKeycloakProvider
            keycloakConfig={getKeycloakConfig()}
            persistor={cookiePersistor}
          >
            <StaticRouter context={context} location={req.url}>
              <App />
            </StaticRouter>
          </SSRKeycloakProvider>
        )
        ...
      })
    
    ...

    Edit your client.js as follow

    import { Cookies, SSRKeycloakProvider } from '@react-keycloak/ssr'
    
    // Create a function to retrieve Keycloak configuration parameters -- 'see examples/razzle-app'
    import { getKeycloakConfig } from './utils'
    
    // 1. Wrap the App inside SSRKeycloakProvider
    hydrate(
      <SSRKeycloakProvider
        keycloakConfig={getKeycloakConfig()}
        persistor={Cookies}
      >
        <BrowserRouter>
          <App />
        </BrowserRouter>
      </SSRKeycloakProvider>,
      document.getElementById('root')
    )
    ...

    Hook Usage

    When a component requires access to Keycloak, you can use the useKeycloak Hook.

    import { useKeycloak } from '@react-keycloak/ssr'
    
    export default () => {
      const { keycloak, initialized } = useKeycloak()
    
      // Here you can access the current keycloak instance methods and variables...
    
      return (
        <div>
          <div>{`User is ${
            !keycloak.authenticated ? 'NOT ' : ''
          }authenticated`}</div>
    
          {!!keycloak.authenticated && (
            <button type="button" onClick={() => keycloak.logout()}>
              Logout
            </button>
          )}
        </div>
      )
    }

    Examples

    See inside examples/nextjs-app and examples/razzle-app folders of @react-keycloak/react-keycloak-examples repository for sample implementations.

    Guides and Articles

    • Migration guide for @react-keycloak/ssr v2.x to v3.x can be found here MIGRATION.md.

    Other Resources

    Securing NextJS API

    Whilst @react-keycloak/ssr can help you secure the Frontend part of a NextJS app if you also want to secure NextJS-exposed APIs you can follow the sample in this issue.

    Thanks to @webdeb for reporting the issue and helping develop a solution.

    External Usage (Advanced)

    If you need to access keycloak instance from non-React files (such as sagas, utils, providers ...), you can retrieve the instance using the exported getKeycloakInstance() method.

    The instance will be initialized by react-keycloak but you'll need to be carefull when using the instance, expecially server-side, and avoid setting/overriding any props, you can however freely access the exposed methods (such as refreshToken, login, etc...).

    Note: This approach is NOT recommended on the server-side because can lead to token leakage issues (see this issue for more details).

    Thanks to @webdeb for requesting this feature and helping develop and test the solution.

    Contributing

    See the contributing guide to learn how to contribute to the repository and the development workflow.

    License

    MIT


    If you found this project to be helpful, please consider buying me a coffee.

    buy me a coffee

    Install

    npm i @react-keycloak/ssr

    DownloadsWeekly Downloads

    8,293

    Version

    3.3.0

    License

    MIT

    Unpacked Size

    83.1 kB

    Total Files

    82

    Last publish

    Collaborators

    • irontony
    • panz3r