React Context provider and hooks for Drupal, with support for Oauth2 authentication
drupal-react-oauth-provider
React Context provider and hooks for Drupal, with support for Oauth2 authentication.
Simplify headless Drupal REST and authentication.
- [x] Written in Typescript
- [x] Zero dependencies
- [x] Drupal 8+
- [ ] Drupal 7 - (Planned)
- [x] Collaboration, feedback, and feature requests welcome
Features
- Context Provider stores Oauth across app
- Abstract away all token management
- Hooks such as
useAPI
,useLazyAPI
, anduseLazyLogin
access REST / JSON:API / Views REST etc. with user credentials in the header - GET, POST, PATCH, and DELETE supported
_format=json
added by default._format=hal_json
can be added manually
Lazy?
Taking inspiration from Apollo GraphQL's useLazyQuery
, the hooks provided can be triggered at any time, instead of when the React component is rendered.
How does it work?
Wrap your React app with DrupalProvider.
import { DrupalProvider } from 'drupal-react-oauth-provider';
const config = {
url: 'https://d9-testing.niallmurphy.dev/',
};
ReactDOM.render(
<React.StrictMode>
<DrupalProvider config={config}>
<App />
</DrupalProvider>
</React.StrictMode>,
document.getElementById('root'),
);
Log in users with useLazyLogin
import { useLazyLogin } from 'drupal-react-oauth-provider';
...
const [login, { loading, error, data }] = useLazyLogin();
...
onClick={() =>
login({ // examples below
username, // 'user1',
password, // '123456',
client_id, // '5e6c8415-9a1f-4d8b-9249-72b9dc6f7494',
client_secret, // 'client_secret_simple_oauth',
grant_type, // 'password',
scope, // 'consumer' < Some Drupal role that's set in oauth
})
}
Check authentication status with authenticated
import { useAuthenticated } from 'drupal-react-oauth-provider';
...
const isAuthenticated = useAuthenticated();
{isAuthenticated ? 'You are authenticated': 'You are not authenticated'}
Make queries with useAPI
or useLazyAPI
Get, post, patch, or delete any data you need. eg. Views.
import { useLazyAPI } from 'drupal-react-oauth-provider';
...
const [lazyAPI, { loading, error, data }] = useLazyAPI();
...
onClick={() =>
lazyAPI({
endpoint: 'node/3',
method: 'PATCH',
body: {
nid: [{ value: '3' }],
type: [{ target_id: 'article' }],
title: [{ value: 'This is hardcoded to show how body works.' }],
},
})
}
Log out with useLazyLogout
import { useLazyLogout } from 'drupal-react-oauth-provider';
...
const [logout] = useLazyLogout();
...
<button onClick={() => logout()}>Logout</button>
Drupal Installation
Requirements
- Oauth2 (Tested with Simple OAuth (OAuth2) & OpenID Connect)
- An oauth client created in Drupal with ID / scope etc.
- Drupal 8+
Recommended
- Enable REST / RESTUI / JSON:API / Views etc.
- Create a "me" user View with
Contextual Filter: User ID: User ID from logged in user
to get user roles etc. Access it withuseAPI
oruseLazyAPI
Note
There is a problem with Jest tests. They require react
and react-dom
as devDependencies, but this breaks production. And help writing more comprehensive tests would be welcome. Unit testing the lazy functions is difficult so I think E2E testing with Cyrpus would work better. I've seen some people say that testing Apollo's lazy queries is difficult.
I hope the Drupal community can share ideas on how to make this better.
Enjoy your headless Drupal.
License: MIT