Adding silent renew entry point to React(create-react-app)

Since the landing page for silent_renew is a just a simple html page, you could bypass webpack. Just put the following file in the public folder. Also, include a copy of the oidc-client.min.js library in the same folder.

public/silent_renew.html:

<!DOCTYPE html>
<html>
<head>
</head>
<body>
  <script src="oidc-client.min.js"></script>
  <script>
      new Oidc.UserManager().signinSilentCallback().then()
  </script>
</body>
</html>

This works at my site in the develepment config. For the production config I have the following in mind (I did not test it yet but I'm pretty confident this is the way forward...).

public/index.js

const express = require('express')
const path = require('path')
const app = express()

app.use(express.static('.'))

app.use((req, res, next) => {
  if (path.extname(req.path).length > 0) {
    next()
  } else if (path.dirname(req.path).indexOf('silent_renew') > -1) {
    req.url = '/silent_renew.html'
    next()
  }
  else if (path.dirname(req.path).indexOf('callback') > -1) {
    req.url = '/callback.html'
    next()
  } else {
    req.url = '/index.html'
    next()
  }
})

app.listen(3000)

As soon as create-react-app supports multiple entry points (I hope this happens soon for enterprise login scenario's) this code becomes obsolete.


You can also take the approach of loading the main bundle in the iframe and capturing the path as mentioned here.

Then you don't need to deal with exposing a path to load the oidc client lib (oidc-client.min.js or redux-oidc.js) or dumping it's content somewhere.

index.js/ts

import * as React from 'react';
import { render } from 'react-dom';
import { processSilentRenew } from 'redux-oidc';
import App from './App';

if (window.location.pathname === '/silent-renew') {
  processSilentRenew();
} else {
  render(<App />, document.getElementById('root'));
}

Please note that /silent-renew request performance can be potentially negatively impacted by large files that loaded along with the application. Some thoughts on it in the comment.


I got it to work by simply adding a route instead of using a separat endpoint. My setup is a create-react-app with redux, redux-oidc & react-router.

I configured the UserManager to use

{
    silent_redirect_uri: `${window.location.protocol}//${window.location.hostname}${window.location.port ? `:${window.location.port}` : ""}/silent_renew`
}

I added this route in my react-router:

<Route exact={true} path={"/silent_renew"} component={SilentRenewComponent} />

The SilentRenewComponnent is a simple function component which calls the redux-oidc function to process the redirect.

import React from "react";
import { processSilentRenew } from "redux-oidc";

export const SilentRenewComponent = () => {
    processSilentRenew();
    return(
        <div>SilentRenewComponent</div>
    );
};