Build a blog admin panel with Refine

4

Authentication provider

Upon creating a new project with Appwrite preset, the CLI automatically creates Auth Provider file.

You'll see a file named src/authProvider.ts created by CLI. This auto-generated file contains pre-defined functions using Appwrite Authentication methods internally to perform authentication and authorization operations.

The auth provider registered to the Refine app by default in the src/App.tsx.

TypeScript

import { authProvider } from './authProvider';
...

 <Refine
    ...
    authProvider={authProvider}
>

Now, we can configure the routing and auth components to manage logins and sign ups.

Routing

Refine offers router bindings and utilities for React Router v6 and improves the user interface with the routerProvider prop. This allows the framework to identify resources from routes and efficiently handle query parameters and navigation tasks.

TypeScript
import routerProvider from '@refinedev/react-router-v6';
import { BrowserRouter } from 'react-router-dom';
import { authProvider } from './authProvider';
...

<BrowserRouter>
    <Refine
        ...
        authProvider={authProvider}
        routerProvider={routerProvider}
    >
    ...
</BrowserRouter>

Login page

We'll use Routes component to connect routing mechanisim along with AuthPage component which returns ready-to-use authentication pages for login, register, update, and forgot password actions.

Update src/App.tsx to the following code.

TypeScript
import { Authenticated, Refine } from "@refinedev/core";
import { dataProvider, liveProvider } from "@refinedev/appwrite";
import {
  AuthPage,
  ErrorComponent,
  RefineThemes,
  ThemedLayoutV2,
  useNotificationProvider,
} from "@refinedev/antd";
import routerProvider, {
  CatchAllNavigate,
  NavigateToResource,
} from "@refinedev/react-router-v6";
import "@refinedev/antd/dist/reset.css";

import { App as AntdApp, ConfigProvider } from "antd";
import { BrowserRouter, Outlet, Route, Routes } from "react-router-dom";

import { appwriteClient } from "./utility";
import { authProvider } from "./authProvider";

const App: React.FC = () => (
  <BrowserRouter>
    <ConfigProvider theme={RefineThemes.Blue}>
      <AntdApp>
        <Refine
          dataProvider={dataProvider(appwriteClient, {
            databaseId: "<APPWRITE_DATABASE_ID>",
          })}
          liveProvider={liveProvider(appwriteClient, {
            databaseId: "<APPWRITE_DATABASE_ID>",
          })}
          authProvider={authProvider}
          routerProvider={routerProvider}
          notificationProvider={useNotificationProvider}
        >
          <Routes>
            <Route
              element={
                <Authenticated 
                  fallback={<CatchAllNavigate to="/login" />}
                >
                  <ThemedLayoutV2>
                    <Outlet />
                  </ThemedLayoutV2>
                </Authenticated>
              }
            ></Route>

            <Route
              element={
                <Authenticated fallback={<Outlet />}>
                  <NavigateToResource 
                    resource="<APPWRITE_COLLECTION_ID>" 
                  />
                </Authenticated>
              }
            >
              <Route
                path="/login"
                element={<AuthPage forgotPasswordLink={false} />}
              />
              <Route path="/register" 
               element={<AuthPage type="register" />} 
              />
            </Route>

            <Route
              element={
                <Authenticated>
                  <ThemedLayoutV2>
                    <Outlet />
                  </ThemedLayoutV2>
                </Authenticated>
              }
            >
              <Route path="*" element={<ErrorComponent />} />
            </Route>
          </Routes>
        </Refine>
      </AntdApp>
    </ConfigProvider>
  </BrowserRouter>
);

export default App;

Key concepts to handle authentication and routing:

  • The <AuthPage> component in Refine includes pages for login, registration, password reset, and password update functionalities.

  • To manage authenticated routes effectively, the <Authenticated> component using to determine the user's authentication status and accordingly directs them or displays relevant elements.

  • Within the <Authenticated> component, we use the <Outlet> component from react-router-dom to render secure routes that are accessible only to authenticated users.

  • We set up a /login route for redirecting unauthenticated users, using Refine's AuthPage components with a type="login" prop to create the login page efficiently.

When you refresh the page, the login screen appears.

Refine login screen

We'll activate the authentication mechanisim with Appwrite in the next section.