Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 0e29239

Browse files
slax57alanpoulain
andauthored
docs: Revamp API Platform Admin docs (#2141)
Co-authored-by: Alan Poulain <contact@alanpoulain.eu>
1 parent f3702bd commit 0e29239

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

46 files changed

+1702
-663
lines changed

‎admin/advanced-customization.md‎

Lines changed: 462 additions & 0 deletions
Large diffs are not rendered by default.

‎admin/authentication-support.md‎

Lines changed: 82 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,24 @@
11
# Authentication Support
22

33
API Platform Admin delegates the authentication support to React Admin.
4-
Refer to [the chapter dedicated to authentication in the React Admin documentation](https://marmelab.com/react-admin/Authentication.html)
5-
for more information.
4+
5+
Refer to the [Auth Provider Setup](https://marmelab.com/react-admin/Authentication.html) documentation for more information.
6+
7+
**Tip:** Once you have set up the authentication, you can also configure React Admin to perform client-side Authorization checks. Refer to the [Authorization](https://marmelab.com/react-admin/Permissions.html) documentation for more information.
68

79
## HydraAdmin
810

9-
The authentication layer for [HydraAdmin component](https://api-platform.com/docs/admin/components/#hydra)
10-
consists of a few parts, which need to be integrated together.
11+
Enabling authentication support for [`<HydraAdmin>` component](./components.md#hydra) consists of a few parts, which need to be integrated together.
12+
13+
In the following steps, we will see how to:
14+
15+
- Make authenticated requests to the API (i.e. include the `Authorization` header)
16+
- Redirect users to the login page if they are not authenticated
17+
- Clear expired tokens when encountering unauthorized `401` response
1118

12-
### Authentication
19+
### Make Authenticated Requests
1320

14-
Add the Bearer token from `localStorage` to request headers.
21+
First, we need to implement a `getHeaders` function, that will add the Bearer token from `localStorage` (if there is one) to the `Authorization` header.
1522

1623
```typescript
1724
const getHeaders = () =>
@@ -20,9 +27,13 @@ const getHeaders = () =>
2027
: {};
2128
```
2229

23-
Extend the Hydra fetch function with custom headers for authentication.
30+
Then, extend the Hydra `fetch` function to use the `getHeaders` function to add the `Authorization` header to the requests.
2431

2532
```typescript
33+
import {
34+
fetchHydra as baseFetchHydra,
35+
} from "@api-platform/admin";
36+
2637
const fetchHydra = (url, options = {}) =>
2738
baseFetchHydra(url, {
2839
...options,
@@ -31,11 +42,14 @@ const fetchHydra = (url, options = {}) =>
3142

3243
```
3344

34-
### Login Redirection
45+
### Redirect To Login Page
3546

36-
Redirect users to a `/login` path, if no token is available in the `localStorage`.
47+
Then, we'll create a `<RedirectToLogin>` component, that will redirect users to the `/login` route if no token is available in the `localStorage`, and call the dataProvider's `introspect` function otherwise.
48+
49+
```tsx
50+
import { Navigate } from "react-router-dom";
51+
import { useIntrospection } from "@api-platform/admin";
3752

38-
```typescript
3953
const RedirectToLogin = () => {
4054
const introspect = useIntrospection();
4155

@@ -47,13 +61,16 @@ const RedirectToLogin = () => {
4761
};
4862
```
4963

50-
### API Documentation Parsing
64+
### Clear Expired Tokens
5165

52-
Extend the `parseHydraDocumentaion` function from the [API Doc Parser library](https://github.com/api-platform/api-doc-parser)
53-
to handle the documentation parsing. Customize it to clear
54-
expired tokens when encountering unauthorized `401` response.
66+
Now, we will extend the `parseHydraDocumentaion` function (imported from the [@api-platform/api-doc-parser](https://github.com/api-platform/api-doc-parser) library).
67+
68+
We will customize it to clear expired tokens when encountering unauthorized `401` response.
5569

5670
```typescript
71+
import { parseHydraDocumentation } from "@api-platform/api-doc-parser";
72+
import { ENTRYPOINT } from "config/entrypoint";
73+
5774
const apiDocumentationParser = (setRedirectToLogin) => async () => {
5875
try {
5976
setRedirectToLogin(false);
@@ -72,11 +89,16 @@ const apiDocumentationParser = (setRedirectToLogin) => async () => {
7289
};
7390
```
7491

75-
### Data Provider
92+
### Extend The Data Provider
7693

77-
Initialize the hydra data provider with custom headers and the documentation parser.
94+
Now, we can initialize the Hydra data provider with the custom `fetchHydra` (with custom headers) and `apiDocumentationParser` functions created earlier.
7895

7996
```typescript
97+
import {
98+
hydraDataProvider as baseHydraDataProvider,
99+
} from "@api-platform/admin";
100+
import { ENTRYPOINT } from "config/entrypoint";
101+
80102
const dataProvider = (setRedirectToLogin) =>
81103
baseHydraDataProvider({
82104
entrypoint: ENTRYPOINT,
@@ -85,12 +107,12 @@ const dataProvider = (setRedirectToLogin) =>
85107
});
86108
```
87109

88-
### Export Admin Component
110+
### Update The Admin Component
89111

90-
Export the Hydra admin component, and track the users' authentication status.
112+
Lastly, we can stitch everything together in the `Admin` component.
91113

92-
```typescript
93-
// components/admin/Admin.tsx
114+
```tsx
115+
// src/Admin.tsx
94116

95117
import Head from "next/head";
96118
import { useState } from "react";
@@ -106,14 +128,14 @@ import { parseHydraDocumentation } from "@api-platform/api-doc-parser";
106128
import authProvider from "utils/authProvider";
107129
import { ENTRYPOINT } from "config/entrypoint";
108130

109-
// Auth, Parser, Provider calls
131+
// Functions and components created in the previous steps:
110132
const getHeaders = () => {...};
111133
const fetchHydra = (url, options = {}) => {...};
112134
const RedirectToLogin = () => {...};
113135
const apiDocumentationParser = (setRedirectToLogin) => async () => {...};
114136
const dataProvider = (setRedirectToLogin) => {...};
115137

116-
const Admin = () => {
138+
exportconst Admin = () => {
117139
const [redirectToLogin, setRedirectToLogin] = useState(false);
118140

119141
return (
@@ -142,29 +164,32 @@ const Admin = () => {
142164
</>
143165
);
144166
};
145-
export default Admin;
146167
```
147168

148-
### Additional Notes
169+
### Example Implementation
149170

150171
For the implementation of the admin component, you can find a working example in the [API Platform's demo application](https://github.com/api-platform/demo/blob/4.0/pwa/components/admin/Admin.tsx).
151172

152173
## OpenApiAdmin
153174

154-
This section explains how to set up and customize the [OpenApiAdmin component](https://api-platform.com/docs/admin/components/#openapi) authentication layer.
155-
It covers:
156-
* Creating a custom HTTP Client
157-
* Data and rest data provider configuration
158-
* Implementation of an auth provider
175+
This section explains how to set up and customize the [`<OpenApiAdmin>` component](./components.md/#openapi) to enable authentication.
159176

160-
### Data Provider & HTTP Client
177+
In the following steps, we will see how to:
161178

162-
Create a custom HTTP client to add authentication tokens to request headers.
163-
Configure the `openApiDataProvider`, and
164-
inject the custom HTTP client into the [Simple REST Data Provider for React-Admin](https://github.com/Serind/ra-data-simple-rest).
179+
- Make authenticated requests to the API (i.e. include the `Authorization` header)
180+
- Implement an authProvider to redirect users to the login page if they are not authenticated, and clear expired tokens when encountering unauthorized `401` response
181+
182+
### Making Authenticated Requests
183+
184+
First, we need to create a custom `httpClient` to add authentication tokens (via the the `Authorization` HTTP header) to requests.
185+
186+
We will then configure `openApiDataProvider` to use [`ra-data-simple-rest`](https://github.com/marmelab/react-admin/blob/master/packages/ra-data-simple-rest/README.md), a simple REST dataProvider for React Admin, and make it use the `httpClient` we created earlier.
165187

166-
**File:** `src/components/jsonDataProvider.tsx`
167188
```typescript
189+
// src/dataProvider.ts
190+
191+
const getAccessToken = () => localStorage.getItem("token");
192+
168193
const httpClient = async (url: string, options: fetchUtils.Options = {}) => {
169194
options.headers = new Headers({
170195
...options.headers,
@@ -177,32 +202,31 @@ const httpClient = async (url: string, options: fetchUtils.Options = {}) => {
177202
return await fetchUtils.fetchJson(url, options);
178203
};
179204

180-
const jsonDataProvider = openApiDataProvider({
205+
const dataProvider = openApiDataProvider({
181206
dataProvider: simpleRestProvider(API_ENTRYPOINT_PATH, httpClient),
182207
entrypoint: API_ENTRYPOINT_PATH,
183208
docEntrypoint: API_DOCS_PATH,
184209
});
185210
```
186211

187-
> [!NOTE]
188-
> The `simpleRestProvider` provider expect the API to include a `Content-Range` header in the response.
189-
> You can find more about the header syntax in the [Mozilla’s MDN documentation: Content-Range](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Range).
190-
>
191-
> The `getAccessToken` function retrieves the JWT token stored in the browser.
212+
**Note:** The `simpleRestProvider` provider expect the API to include a `Content-Range` header in the response. You can find more about the header syntax in the [Mozilla’s MDN documentation: Content-Range](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Range).
213+
214+
**Note:** The `getAccessToken` function retrieves the JWT token stored in the browser's localStorage. Replace it with your own logic in case you don't store the token that way.
192215

193-
### Authentication and Authorization
216+
### Creating The AuthProvider
194217

195-
Create and export an `authProvider` object that handles authentication and authorization logic.
218+
Now let's create and export an `authProvider` object that handles authentication and authorization logic.
196219

197-
**File:** `src/components/authProvider.tsx`
198220
```typescript
221+
// src/authProvider.ts
222+
199223
interface JwtPayload {
200-
exp?: number;
201-
iat?: number;
202-
roles: string[];
224+
sub: string;
203225
username: string;
204226
}
205227

228+
const getAccessToken = () => localStorage.getItem("token");
229+
206230
const authProvider = {
207231
login: async ({username, password}: { username: string; password: string }) => {
208232
const request = new Request(API_AUTH_PATH, {
@@ -242,7 +266,7 @@ const authProvider = {
242266
const decoded = jwtDecode<JwtPayload>(token);
243267

244268
return Promise.resolve({
245-
id: "",
269+
id: decoded.sub,
246270
fullName: decoded.username,
247271
avatar: "",
248272
});
@@ -253,20 +277,23 @@ const authProvider = {
253277
export default authProvider;
254278
```
255279

256-
### Export OpenApiAdmin Component
280+
### Updating The Admin Component
257281

258-
**File:** `src/App.tsx`
259-
```typescript
260-
import {OpenApiAdmin} from '@api-platform/admin';
261-
import authProvider from "./components/authProvider";
262-
import jsonDataProvider from "./components/jsonDataProvider";
263-
import {API_DOCS_PATH, API_ENTRYPOINT_PATH} from "./config/api";
282+
Finally, we can update the `Admin` component to use the `authProvider` and `dataProvider` we created earlier.
283+
284+
```tsx
285+
// src/Admin.tsx
286+
287+
import { OpenApiAdmin } from '@api-platform/admin';
288+
import authProvider from "./authProvider";
289+
import dataProvider from "./dataProvider";
290+
import { API_DOCS_PATH, API_ENTRYPOINT_PATH } from "./config/api";
264291

265292
export default () => (
266293
<OpenApiAdmin
267294
entrypoint={API_ENTRYPOINT_PATH}
268295
docEntrypoint={API_DOCS_PATH}
269-
dataProvider={jsonDataProvider}
296+
dataProvider={dataProvider}
270297
authProvider={authProvider}
271298
/>
272299
);

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /