Example UI application handles logins to OIDC provider and loads Helsinki Profile. There are two types of logins: Tunnistamo and Helsinki-tunnistus. User chooses one on the index page.
App uses oidc-react.js for all calls to the OIDC provider. Library is wrapped with "client" (client/index.ts) to unify connections to Tunnistamo, Keycloak server and Profiili API.
Included in this demo app:
- two login types
- hooks for easy usage with React
- redux store listening a client
- HOC component listening a client and showing different content for authorized and unauthorized users.
- getting API token and using it to get Profile
Client dispatches events and trigger changes which then trigger re-rendering of the components using the client.
Configs are in .env -files.
Tunnistamo does not support silent login checks (it uses only sessionStorage) so REACT_APP_OIDC_AUTO_SIGN_IN must be 'false'. It renews access tokens so REACT_APP_OIDC_SILENT_AUTH_PATH must be changed to '/' to prevent errors for unknown redirect url.
Config can also be overridden for command line:
REACT_APP_OIDC_URL="https://foo.bar"
Scripts generates first environment variables to public/env-config.js
with scripts/update-runtime-env.ts
, which contains the
actual used variables when running the app. App is not using CRA's default process.env
way to refer of variables but
window._env_
object.
Note that running built application locally you need to generate also public/env-config.js
file. It can be done with
yarn update-runtime-env
. By default it's generated for development environment if no NODE_ENV
is set.
Settings when using Tunnistamo authentication:
REACT_APP_OIDC_URL="<SERVER_URL>/auth"
REACT_APP_OIDC_REALM=""
REACT_APP_OIDC_SCOPE="profile"
REACT_APP_OIDC_CLIENT_ID="exampleapp-ui"
Settings when using Helsinki-tunnistus authentication:
REACT_APP_KEYCLOAK_URL="<SERVER_URL>/auth"
REACT_APP_KEYCLOAK_REALM="helsinki-tunnistus"
REACT_APP_KEYCLOAK_SCOPE="profile"
REACT_APP_KEYCLOAK_CLIENT_ID="exampleapp-ui"
Keys are the same, but with "_OIDC_" replaced by "_KEYCLOAK_".
Use same config as above with Tunnistamo and add
REACT_APP_OIDC_SCOPE="openid profile email https://api.hel.fi/auth/helsinkiprofile"
REACT_APP_OIDC_PROFILE_API_TOKEN_AUDIENCE="https://api.hel.fi/auth/helsinkiprofiledev"
Tunnistamo does not use these, so leave them empty:
REACT_APP_OIDC_API_TOKEN_GRANT_TYPE=""
REACT_APP_OIDC_API_TOKEN_PERMISSION=""
Use same config as above with Helsinki-tunnistus and add
REACT_APP_KEYCLOAK_SCOPE="openid profile email"
REACT_APP_KEYCLOAK_PROFILE_API_TOKEN_AUDIENCE="https://api.hel.fi/auth/helsinkiprofiledev"
REACT_APP_KEYCLOAK_API_TOKEN_GRANT_TYPE="api token grant type in Helsinki-Tunnistus"
REACT_APP_KEYCLOAK_API_TOKEN_PERMISSION="api token permission in Helsinki-Tunnistus"
When getting api tokens, the Tunnistamo request does not need any props. But audiences are needed when getting the correct token in UI. Note that REACT_APP_OIDC_SCOPE
must have scopes for the api token audiences when using Tunnistamo.
REACT_APP_OIDC_EXAMPLE_API_TOKEN_AUDIENCE="api token audience in Tunnistamo"
Tunnistamo does not use these, so leave them empty:
REACT_APP_OIDC_API_TOKEN_GRANT_TYPE=""
REACT_APP_OIDC_API_TOKEN_PERMISSION=""
This server uses the audience, grant type and permission.
REACT_APP_KEYCLOAK_EXAMPLE_API_TOKEN_AUDIENCE="example api token audience in Helsinki-Tunnistus"
REACT_APP_KEYCLOAK_API_TOKEN_GRANT_TYPE="api token grant type in Helsinki-Tunnistus"
REACT_APP_KEYCLOAK_API_TOKEN_PERMISSION="api token permission in Helsinki-Tunnistus"
Docker image has ".env"-file baked in, so it uses production environment variables by default. To make the image work in other environments, env vars must be overridden.
You can pass new env vars easily with '--env-file' argument. Of course '-e' works too.
docker run --env-file=.env.development -p 3000:8080 helsinki/example-ui-profile
Note that the composed build will stop to the 'development' stage in Dockerfile and uses 'react-scripts start' command and not nginx.
The env-file is fixed to '.env.development" in the 'docker-compose.yml'.
docker compose up
Env vars can be overridden in the yaml-file.
Example:
services:
app:
environment:
- REACT_APP_OIDC_URL=https://foo.bar
Runs tests in watch mode.
Scripts generates first environment variables to public/test-env-config.js
with scripts/update-runtime-env.ts
, which contains the
actual used variables when running the app. App is not using CRA's default process.env
way to refer of variables but
window._env_
object.
Runs tests with coverage outputted to console. Results are saved to /coverage Note: command is run with "CI=true". Remove this to get visually clearer results (with colors!).
Runs tests with coverage and its results are saved as an xml file by jest-sonar-reporter. This file can be sent to Sonar with Sonar Scanner (CLI). Report is /reports
Generates variable object used when app is running. Generated object is stored at public/env-config.js
and available
as window._env_
object.
Generation uses react-scripts
internals, so values come from either environment variables or files (according
react-scripts documentation).
Firefox and Safari are stricter with third-party cookies and therefore session checks in iframes fail with Firefox and Safari, when using localhost with Keycloak. Login works, but session checks fail immediately. There are no known issues with Tunnistamo.
Third party cookies are not an issue, when service is deployed and servers have same top level domains like *.hel.ninja. The problem occurs locally, because http://localhost:3000 is communicating with https://*.dev.hel.ninja.
More info about Firefox: https://developer.mozilla.org/en-US/docs/Web/Privacy/Storage_Access_Policy/Errors/CookiePartitionedForeign
Issue can be temporarily resolved with: https://developer.mozilla.org/en-US/docs/Web/Privacy/State_Partitioning#disable_dynamic_state_partitioning
With Safari, go to "Settings" -> "Privacy" -> uncheck "Prevent cross-site tracking"