Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cookie-based authentication via REST API in react-admin

I'm new to react-admin. I already read through all the questions here in stackoverflow, and google'd for my question too, but did not find any useful solution.

I am setting up React-admin to replace an existing admin page for one of my projects. I use cookie-based authentication via REST API.

Is it possible (and if yes how?) to use it in react-admin? Can someone please lead me to the right direction?

Cheers!

like image 374
Reka Karolyi Avatar asked Feb 15 '19 23:02

Reka Karolyi


People also ask

What is authProvider in react?

Just like a dataProvider , an authProvider is an object that handles authentication and authorization logic. It exposes methods that react-admin calls when needed, and that you can call manually through specialized hooks. The authProvider methods must return a Promise.

Is react-admin Secure?

React-admin lets you secure your admin app with the authentication strategy of your choice. Since there are many different possible strategies (Basic Auth, JWT, OAuth, etc.), react-admin simply provides hooks to execute your own authentication code. By default, react-admin apps don't require authentication.

How does cookie based authentication work in Jira?

This is how cookie-based authentication works in Jira at a high level: The client creates a new session for the user, via the Jira REST API . Jira returns a session object, which has information about the session including the session cookie. The client stores this session object.

When to use REST API in ReactJS?

Generally in a ReactJS application, we use the Rest API to get the data or save the data. Even for login the user, we use the API endpoint. For the rest of the blog, we assume that the API endpoint would return the JWT after the user is authenticated.

Can ReactJS authenticate a user?

This hampers the ability for the application to authorize itself for third-party API calls. However, this does not disable its ability to authenticate. In the rest of this article, we are going to use ReactJS to build an application that can authenticate users.

How to use Jira REST API authentication?

In most cases, the first step in using the Jira REST API is to authenticate a user account with your Jira site. Any authentication that works against Jira will work against the REST API. In this tutorial, we will use cookie-based (session) authentication. This is how cookie-based authentication works in Jira at a high level:


Video Answer


1 Answers

It is possible of course. You just have to make fetch use cookies.

react-admin uses fetch to send http requests to your back-end. And fetch does not send cookies by default.

So to make fetch send cookies, you have to add the credentials: 'include' option for every fetch call the app makes.

(if your admin and api are not on the same domain, you will have to enable CORS on your back-end.)

See react-admin's doc for how to customize requests on the dataProvider here: https://github.com/marmelab/react-admin/blob/master/docs/Authentication.md#sending-credentials-to-the-api

import { fetchUtils, Admin, Resource } from 'react-admin';
import simpleRestProvider from 'ra-data-simple-rest';

const httpClient = (url, options = {}) => {
    if (!options.headers) {
        options.headers = new Headers({ Accept: 'application/json' });
    }
    const token = localStorage.getItem('token');
    options.headers.set('Authorization', `Bearer ${token}`);
    return fetchUtils.fetchJson(url, options);
}
const dataProvider = simpleRestProvider('http://localhost:3000', httpClient);

const App = () => (
    <Admin dataProvider={dataProvider} authProvider={authProvider}>
        ...
    </Admin>
);

You'll have to customize this to add options.credentials = 'include' like so :

const httpClient = (url, options = {}) => {
    if (!options.headers) {
        options.headers = new Headers({
          Accept: 'application/json'
        });
    }
    options.credentials = 'include';
    return fetchUtils.fetchJson(url, options);
}

You will have to do the same thing for the authProvider.

Something like

// in src/authProvider.js
export default (type, params) => {
    // called when the user attempts to log in
    if (type === AUTH_LOGIN) {
        const { username, password } = params;
        const request = new Request(`${loginUri}`, {
            method: 'POST',
            body: JSON.stringify({ username: username, password }),
            credentials: 'include',
            headers: new Headers({ 'Content-Type': 'application/json' }),
        });
        return fetch(request)
        .then(response => {
            if (response.status < 200 || response.status >= 300) throw new Error(response.statusText);

            localStorage.setItem('authenticated', true);
        });
    }
    // called when the user clicks on the logout button
like image 142
Armel Larcier Avatar answered Oct 13 '22 10:10

Armel Larcier