Best practices for implementing Django backend authentication with NextJS frontend forms

I've created an API hub using Django and a frontend application with NextJS. Currently, I'm working on implementing authentication from the NextJS app to the Django API and I'm seeking advice on best practices.

At the moment, the NextJS app sends the user's username and password to an endpoint, which then returns either the user's token or an error if there is an issue.

React

  const login = async () => {
    let token = await axios.post('/api/accounts/', {
      email: email,
      password: password
    }).then(r => r.data.token).catch(function (error) { console.log(error) })

      if (token) {
        router.push({
            pathname: '/home/',
            query: { token: token },
          })
        }
      }

NextJS server api/accounts

export default async (req, res) => {
  if (req.method === 'POST') {
    try {
      // retrieve payment intent data
      const {data} = await axios.post('https://website/api/api-token-auth/', req.body)
      res.status(200).send(data)
    } catch (err) {
      res.status(500).json({ statusCode: 500, message: err.message })
    }
  } else {
    res.setHeader('Allow', 'POST')
    res.status(405).end('Method Not Allowed')
  }
}

Django API

@csrf_exempt
@api_view(["POST"])
@permission_classes((AllowAny,))
def obtain_auth_token(request):
    email = request.data.get("email")
    password = request.data.get("password")
    if email is None or password is None:
        return Response({'error': 'Please provide both email and password'},
                        status=HTTP_400_BAD_REQUEST)
    user = authenticate(email=email, password=password)
    if not user:
        return Response({'error': 'Invalid Credentials'},
                        status=HTTP_404_NOT_FOUND)

    token, _ = Token.objects.get_or_create(user=user)
    return Response({'token': token.key},
                    status=HTTP_200_OK)

After receiving the token, I redirect the user to the homepage.

My queries are:

  1. Is my current method of authenticating users effective? Am I missing anything crucial? This is my first attempt at authentication and I want to ensure it's done correctly.

  2. How should I securely store this token? What is considered "best practice" for handling authentication credentials? I'm considering passing the token to every component that requires it or storing it in LocalStorage, but I'm unsure of the most common approach.

Any guidance you can offer would be greatly appreciated!

Thank you in advance!

Answer №1

Is my method of authenticating users effective? Am I missing anything important? This is my first time implementing authentication for something I've created, so I want to make sure I'm doing it right.

  • The Python Backend code looks good overall. However, reinventing token authentication may not be necessary as Token Authentication is already available. You could consider using TokenAuthentication directly instead of creating your own implementation.

  • It appears that the nexjs server may not be serving a significant purpose. Why introduce an additional intermediate service between the frontend and API REST? Additionally, there seems to be a flaw in how response redirection handles authentication failures with status codes - specifically overriding them with a 500 status code:

    try {
        // retrieve payment intent data
        const {data} = await axios.post('https://website/api/api-token-auth/', req.body)
        res.status(200).send(data)
     } catch (err) {
        // if err status code is 404 e.g. bad credentials, response status is 500 where it should be 404.
        res.status(500).json({ statusCode: 500, message: err.message })
     } 
    

What is the best practice for storing authentication tokens? Should I pass the token around to every component needing it or utilize LocalStorage? I am uncertain about the most common approach in these scenarios.

Avoid using cookies to prevent CSRF attacks. While Local Storage is a convenient solution, it exposes the token to XSS attacks. However, considering you are already using HTTPS, Local Storage can be a viable option. In the event of an XSS attack, exposure of the token would likely mean extensive compromise. More details on this topic can be found here

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Trouble with React Material Select Options Failing to Populate

After iterating and producing MenuItems, I am able to see the items when I console.log, but in the UI, the dropdown appears empty. I'm puzzled as to why the Select's are not being populated. Any thoughts on this issue? Below is the supplied code ...

Can anyone suggest a more efficient method for specifying the type of a collection of react components?

Picture this scenario: you are extracting data from an API and creating a list of Card components to be displayed in a parent component. Your code might resemble the following: function App() { let items = [] // How can I specify the type here to avoid ...

Tips for incorporating constants and functions into a React Component class

Looking at the AppBar code from Material-UI: https://material-ui.com/components/app-bar/#app-bar-with-a-primary-search-field I came across a section called "renderMobileMenu" which I want to integrate into my React Component class. However, the sample cod ...

A guide on implementing listings in React Native through the use of loops

I am trying to display the data retrieved from an API, but I am encountering an error. // Retrieving the data. componentWillMount() { tokenner() .then(responseJson => { const token = "Bearer " + responseJson.result.token; ...

How to open a new tab in ReactJS

When attempting to open a component in a new tab using the Link in React router, it results in a 404 error page being displayed instead of the desired react component. The main React entry point file (js), import React from 'react'; import { re ...

What could be causing the error message 'Please activate javascript' to appear in my React.js application?

I encountered the you need to enable javascript to run this app error in my MERN stack application. Every aspect works well except for an API call made for a specific route. I utilize the axios package and all API calls within the application successfully ...

Exploring nested arrays of objects and applying value constraints

Is there a way to iterate through an array and display only 5 items at once, with the option to call a function on click that will add another 20 items? I have an object structured like this: let someObject = [ { data: [ { id: 123, ...

Capturing mouse coordinates from hover events in Highcharts Gantt using the highcharts-react library

Currently, I am utilizing the official React highcharts wrapper to create a Gantt chart. My goal is to obtain precise mouse coordinates from a mouse-over event and utilize them for a custom tooltip. For instance: https://stackblitz.com/edit/react-c5mivs ...

Is the use of constructors, binding, (super), and lifecycle methods still prevalent in reactJS development?

Excuse me, I am fairly new to reactJS and after going through numerous tutorials including the ones on the official website, I find myself quite confused. It appears that there have been many updates over the past few years with reactJS, leading to differe ...

Addressing memory leaks in React server-side rendering and Node.js with setInterval

Currently in my all-encompassing react application, there's a react element that has setInterval within componentWillMount and clearInterval inside componentWillUnmount. Luckily, componentWillUnmount is not invoked on the server. componentWillMount( ...

Using the ref callback to access getBoundingClientRect values in React Components

I'm having some trouble extracting data using the getBoundingClientRect() method from a set of animated div elements. The issue I'm facing is that the refCallback function is returning empty DOMRect objects. If you're interested, feel free t ...

Issue with Chrome not triggering onMouseEnter event when an element blocking the cursor disappears in React

Important Note: This issue seems to be specific to Chrome Currently, React does not trigger the onMouseEnter event when a blocking element disappears. This behavior is different from standard JavaScript events and even delegated events. Below is a simpli ...

What is the best way to show an SVG icon in React without having to make an HTTP request for the file?

A special requirement for a react application is to display icons in certain parts of the application while offline. The use of inline svg is particularly fitting for this purpose. import React from 'react'; // Utilizing inline svg to showcase i ...

Encountered an error when attempting to load the external module @babel/register during the

My React project runs smoothly on my VMware, but when I cloned the same app and executed the gulp command, I encountered an error during compilation: MacBook-Pro:Frontend1.0 apurvgandhwani$ gulp [18:42:31] Failed to load external module @babel/register ...

Single-select components in React Native

I am currently working on implementing a simple single selectable item feature, illustrated in the image provided below. https://i.stack.imgur.com/U2rJd.png At this moment, I have set up an array containing my data items and utilized the .map function to ...

Encountering Nested CSS bugs while implementing Tailwind in a Next.js/React project

Just diving into the world of Next.js/React. I recently went through the Tailwind CSS for Next.js tutorial and successfully integrated Tailwind into my project by following these steps: npm install -D tailwindcss postcss autoprefixer npx tailwindcss init - ...

Tips for reducing the gap between the border and text within a Textfield element in Material UI

Check out my UI Working on my Reactjs project and grappling with styling the material ui Textfield component. const styles = theme => ({ input: { width: 30, height:30, marginTop:10, fontSize:7, padding:0, ...

A guide on updating various states using React Hooks

Creating a background component with the use of Vanta in NextJS, here's the code snippet: import { useEffect, useRef, useState } from "react"; import * as THREE from "three"; import FOG from "vanta/dist/vanta.fog.min"; im ...

Issue with Material UI: Warning - The <td> element should not be placed inside a <div> element

In my project, I am utilizing React, typescript, and Material UI. One of the components I have created is a standard "Create user form" with basic input fields for username, name, email, etc. I have also included buttons for "Edit" and "Delete." While ever ...

Steps for removing the bottom border for the last child in the Material UI Box Component

I have a Box Component where ListItems are wrapped. For each child, I have a border-bottom of 1px solid class set for the Box component, but I don't want it for the last child. How can I achieve that? {data.map((item, i) => { return ...