Published on

Authentication using OpenId in React/NextJs App With Orchard Core - Part 2

Table of Contents


In this post we will see how to do authentication using OpenId for a React App using Orchard Core.


To create the CMS and and a sample content follow the Getting started

Create a OpenId Client

Navigate to the https://localhost:5001/Admin and login as a admin.

Navigate to Security -> OpenID Connect -> Scopes -> Add an scope.

Create two scopes role and openid.

Navigate to Security -> OpenID Connect -> Applications -> Add an Application.

Create a client with

Client id : client1

Display Name : client1

Type : Public client

Flows : Allow Authorization Code Flow

Redirect Uris : http://localhost:3000

Consent type: Explicit consent

Allowed scopes: openid, role

Click Save

Update the CORS policy

Create a new policy to and set is as default. All credentials and any origin, headers and methods.

Update the CORS in CMS Startup.cs file under ConfigureServices function.

public void ConfigureServices(IServiceCollection services)
    services.AddCors(o => o.AddDefaultPolicy(builder =>

Create a NextJS App

yarn create next-app --typescript

Add npm packages

yarn add oidc-client-ts react-oidc-context @apollo/client

Add .env file


Create login component

Inside the components folder create Login.tsx

import React from 'react'
import { useAuth } from 'react-oidc-context';

const Login = () => {
    const auth = useAuth();
    if (auth.isLoading) {
      return <div>Loading...</div>;

    if (auth.error) {
      return <div>Oops... {auth.error.message}</div>;

    if (auth.isAuthenticated) {
      return (
          Hello {auth.user?.profile.sub}{" "}
          <button onClick={auth.removeUser}>Log out</button>

    return <button onClick={auth.signinRedirect}>Log in</button>;

export default Login

Create Languages component

Inside the components folder create Languages.tsx

import React from "react";
import { gql, useQuery } from "@apollo/client";

interface Props {}

const LanguagesQuery = gql`
  query Languages {
    language {

const Languages = (props: Props) => {
  const { loading, error, data } = useQuery(LanguagesQuery);

  if (loading) return <p>Loading...</p>;
  if (error) return <p>Error :(</p>;

  return any) => (
    <div key={lang.code}>

export default Languages;

Create apollo client

Create a file apollo-client.ts inside the lib folder.

import { ApolloClient, createHttpLink, InMemoryCache } from '@apollo/client'
import { setContext } from '@apollo/client/link/context'
import { User } from 'oidc-client-ts'

const httpLink = createHttpLink({
  uri: process.env.NEXT_PUBLIC_GRAPHQL_URL,

const authLink = setContext((_, { headers }) => {
  // get the authentication token from local storage if it exists
  const oidcStorage = sessionStorage.getItem(
  const token = User.fromStorageString(oidcStorage!).access_token
  // return the headers to the context so httpLink can read them
  return {
    headers: {
      authorization: token ? `Bearer ${token}` : '',
const client = new ApolloClient({
  link: authLink.concat(httpLink),
  cache: new InMemoryCache(),
export default client

Update _app.tsx

import '../styles/globals.css'
import type { AppProps } from 'next/app'
import { AuthProvider } from "react-oidc-context";
import { ApolloProvider } from "@apollo/client";
import client from '../lib/apollo-client';
function MyApp({ Component, pageProps }: AppProps) {
  const oidcConfig = {
    authority: "https://localhost:5001",
    client_id: "client1",
    redirect_uri: "http://localhost:3000",
    response_type: "code",
    scopes: "openid email"
  const onSignin = () => {
    location.href = "/";
  return (
    <AuthProvider {...oidcConfig} onSigninCallback={onSignin}>
      <ApolloProvider client={client}>
        <Component {...pageProps} />

export default MyApp

Update the index page

import type { NextPage } from 'next'
import Login from './../components/Login';
import Languages from './../components/Languages'

const Home: NextPage = () => {
    return (
        <Login />

export default Home

Run both CMS and Next app

Navigate to the CMS project and run

dotnet run

Navigate to the NextJS project and run

yarn // To install the npm packages
yarn dev // To run the app

Repo :