AWS: Unlocking Seamless Communication between S3 Frontend (React, Axios) and EC2 Backend (Python3/Django, DjangoREST, corsheaders)
Image by Estefan - hkhazo.biz.id

AWS: Unlocking Seamless Communication between S3 Frontend (React, Axios) and EC2 Backend (Python3/Django, DjangoREST, corsheaders)

Posted on

Are you struggling to connect the dots between your S3 frontend (built with React and Axios) and EC2 backend (running Python3, Django, DjangoREST, and corsheaders)? Worry no more! In this comprehensive guide, we’ll decipher the mystery of allowing your frontend to communicate with your backend, effortlessly.

Understanding the Architecture

Before diving into the nitty-gritty, let’s take a step back and visualize our architecture:

Component Description
S3 Frontend React application hosted on Amazon S3, using Axios for HTTP requests
EC2 Backend Python3 application running on Amazon EC2, using Django, DjangoREST, and corsheaders for API management

This architecture is a great example of a decoupled system, allowing for scalability and maintainability. However, it also introduces a challenge: enabling communication between the frontend and backend.

Configuring CORS on EC2 Backend (Django)

CROSS-ORIGIN RESOURCE SHARING (CORS) is a security feature implemented in web browsers to prevent malicious activities. To allow our frontend to communicate with our backend, we need to configure CORS on our EC2 backend.

Install the `corsheaders` package using pip:

pip install corsheaders

Next, add `corsheaders` to your Django project’s `INSTALLED_APPS` setting:


INSTALLED_APPS = [
    # ...
    'corsheaders',
    # ...
]

Now, add the following configuration to your Django project’s `settings.py` file:


CORS_ORIGIN_WHITELIST = [
    'http://localhost:3000',  # Your React frontend URL
    'https://example.com'  # Your production URL
]

CORS_ALLOW_METHODS = [
    'GET',
    'POST',
    'PUT',
    'PATCH',
    'DELETE',
    'OPTIONS'
]

CORS_ALLOW_HEADERS = [
    'accept',
    'accept-encoding',
    'authorization',
    'content-type',
    'dnt',
    'origin',
    'user-agent',
    'x-csrftoken',
    'x-requested-with',
]

This configuration allows CORS requests from the specified origins, methods, and headers.

Enabling Axios to Send CORS Requests

By default, Axios doesn’t send CORS requests. We need to configure Axios to include the necessary headers:


import axios from 'axios';

axios.defaults.headers.common['Access-Control-Allow-Origin'] = '*';
axios.defaults.headers.common['Access-Control-Allow-Headers'] = 'Authorization, Content-Type';
axios.defaults.headers.common['Access-Control-Allow-Methods'] = 'GET, POST, PUT, PATCH, DELETE, OPTIONS';

This configuration sets the necessary headers for Axios to send CORS requests.

Handling CORS Preflight Requests

When making a request from the frontend to the backend, the browser sends a preflight request (OPTIONS method) to check if the request is allowed. We need to handle this preflight request on our backend:


from rest_framework.response import Response
from rest_framework.views import APIView

class CorsView(APIView):
    def options(self, request, *args, **kwargs):
        return Response(status=200)

This view handles the preflight request by returning a 200 OK response.

Securing Your API with CSRF Token

To add an extra layer of security, we’ll use Django’s built-in CSRF protection:


from rest_framework.authentication import SessionAuthentication
from rest_framework.csrf import csrf_exempt

class CsrfExemptSessionAuthentication(SessionAuthentication):
    def enforce_csrf(self, request):
        return

This custom authentication class exempts CSRF checks for our API views.

Putting it All Together

Now that we’ve configured CORS on our backend and Axios on our frontend, let’s create a simple API view to test our communication:


from rest_framework.response import Response
from rest_framework.views import APIView

class HelloView(APIView):
    def get(self, request):
        return Response({'message': 'Hello from Django!'})

On your React frontend, create a component to make a GET request to this API view:


import React, { useState, useEffect } from 'react';
import axios from 'axios';

function App() {
  const [message, setMessage] = useState('');

  useEffect(() => {
    axios.get('https://your-ec2-instance.com/hello/')
      .then(response => {
        setMessage(response.data.message);
      })
      .catch(error => {
        console.error(error);
      });
  }, []);

  return (
    <div>
      <p>{message}</p>
    </div>
  );
}

export default App;

Run your React application, and you should see the message “Hello from Django!” displayed on your page.

Conclusion

Voilà! You’ve successfully enabled communication between your S3 frontend (React, Axios) and EC2 backend (Python3/Django, DjangoREST, corsheaders). This architecture provides a solid foundation for building scalable and maintainable applications. Remember to stay vigilant about security and keep your CORS configuration up-to-date to ensure the integrity of your system.

Additional Resources

Happy coding!

Frequently Asked Question

Got stuck with your AWS setup? Don’t worry, we’ve got you covered! Here are some frequently asked questions about letting a S3 frontend communicate with an EC2 backend.

What is the best way to set up CORS headers on my EC2 backend to allow communication with my S3 frontend?

To enable CORS on your EC2 backend, you’ll need to install the corsheaders package in your Django project. Add ‘corsheaders’ to your INSTALLED_APPS in settings.py, then add CORS_ALLOWED_ORIGINS = [‘*’] or specify the domains you want to allow. Next, add the CorsMiddleware to your MIDDLEWARE sequence. Finally, in your Django REST framework API views, add the @csrf_exempt decorator to allow cross-origin requests.

How do I configure Axios in my React frontend to send requests to my EC2 backend?

In your React component, import Axios and set the base URL to your EC2 backend’s domain. For example, axios.create({ baseURL: ‘https://example.com/api/’ }). Then, use the Axios instance to send requests to your backend API endpoints. Make sure to include the API endpoint URL in your request. If you’re using a proxy, you can set it up in your package.json file with the “proxy” field.

Do I need to use an SSL certificate on my EC2 backend for secure communication with my S3 frontend?

Yes, it’s highly recommended to use an SSL certificate on your EC2 backend to ensure secure communication with your S3 frontend. You can obtain an SSL certificate from AWS Certificate Manager (ACM) or a third-party provider, then configure your EC2 instance to use it. This will encrypt the data transmitted between your frontend and backend, protecting your users’ data.

How do I handle authentication and authorization between my S3 frontend and EC2 backend?

You can implement authentication and authorization using JSON Web Tokens (JWT) or OAuth. On your EC2 backend, generate a token upon user login and return it to the frontend. The frontend can then include the token in the Authorization header of subsequent requests. Your backend can verify the token and authorize access to resources accordingly. You can also use AWS Cognito or other identity providers for a more robust solution.

What are some common pitfalls to avoid when setting up communication between my S3 frontend and EC2 backend?

Some common pitfalls to avoid include not configuring CORS correctly, forgetting to add the necessary headers or middleware, misconfiguring Axios or your proxy, and neglecting to implement authentication and authorization. Additionally, ensure your EC2 instance and S3 bucket are in the same region, and your security groups and network ACLs are configured to allow communication between them.