簡體   English   中英

如何使用 React 和 Django 使用環境變量正確保護 API 登錄憑據

[英]How to properly secure API login credentials with environment variables using React and Django

我有一個使用 React(前端)和 Django Rest 框架(后端)的項目,它目前部署在 PythonAnywhere 上。 我正在使用 axios 連接到我的 API 並將數據從我的數據庫加載到 React 前端。

在開發過程中,我將用於訪問數據庫的用戶名和密碼硬編碼到我的index.js文件中(憑據在下面被隱藏了):

import React from 'react';
import ReactDOM from 'react-dom';
import App from './components/App.js';
import axios from 'axios';

import 'semantic-ui-css/semantic.min.css';
import 'lightgallery.js/dist/css/lightgallery.css';
import './styles.css';
import * as serviceWorker from './serviceWorker';

axios.defaults.xsrfHeaderName = "X-CSRFTOKEN";
axios.defaults.xsrfCookieName = "csrftoken";
axios.defaults.withCredentials = true;

axios.post('/login/', { username: [HARD_CODED_USERNAME], password: [HARD_CODED_PASSWORD] }).then(rv => {
    console.log('Login', rv)
}).catch(err => {
    console.log('Login error', err.response)
});

const updatePhoto = () => {
    axios.patch('https://[WEBSITEADDRESS.COM]/api/photos/').then(resp => {
        console.log('Update response', resp)
    }).catch(error => {
        console.log("Update error", error)
    })
}

ReactDOM.render(
    <App />,
  document.getElementById('root')
);

serviceWorker.unregister();

這可行,但是在瀏覽器中檢查后可以查看用戶名和密碼。 不僅如此,任何人都可以訪問 Django 管理員和 API,因為它會使用我的用戶名和密碼自動登錄!

然后我嘗試使用位於我的 create-react-app 項目根目錄的.env文件(與我的package.json文件級別相同):

REACT_APP_USERNAME=myusername
REACT_APP_PASSWORD=mypassword

我將我的index.js文件更新為如下:

const my_user_name = process.env.REACT_APP_USERNAME;
const my_password = process.env.REACT_APP_PASSWORD; 

axios.post('/login/', { username: my_user_name, password: my_password }).then(rv => {
    console.log('Login', rv)
}).catch(err => {
    console.log('Login error', err.response)
});

但是,這仍然不會掩蓋瀏覽器中檢查的憑據,雖然它確實解決了自動將任何人登錄到我的 Django 管理員和 API 的問題,但來自數據庫的數據並未顯示在網站上。

我的問題如下:

  1. 如何正確設置 axios 以訪問我的 API 並在我的網站上顯示數據而無需將某人登錄到我的 Django 管理員?
  2. 使用瀏覽器的檢查工具時,如何在 React 中正確設置環境變量以隱藏敏感數據?

任何幫助深表感謝!

更新:解決方案

根據@Lior_Pollak 在下面對他的回答的評論,我設法通過在后端創建一個公共的只讀 API 端點來解決我的兩個問題。 任何人都可以查看 API,但不能發布、更新或刪除數據,也不能訪問 Django 管理員。 並且瀏覽器的檢測工具中沒有顯示敏感數據,但我的所有照片都顯示在網站上。 :)

萬一其他人偶然發現了這個問題,我在下面提供了我成功使用的代碼(后端和前端):

前端: index.js

import React from 'react';
import ReactDOM from 'react-dom';
import App from './components/App.js';

import 'semantic-ui-css/semantic.min.css';
import 'lightgallery.js/dist/css/lightgallery.css';
import './styles.css';
import * as serviceWorker from './serviceWorker';

/*Removed all code related to axios; was not needed here*/

ReactDOM.render(
    <App />,
  document.getElementById('root')
);

serviceWorker.unregister();

后端: views.py

from django.views.generic import View
from django.http import HttpResponse
from django.conf import settings

from rest_framework import generics
from rest_framework import permissions

from .models import Photo
from .serializers import PhotoSerializer

import logging
import os

class PhotoList(generics.ListCreateAPIView):
    permission_classes = [permissions.IsAuthenticatedOrReadOnly]
    queryset = Photo.objects.filter(show=True).order_by('order')
    serializer_class = PhotoSerializer

class FrontendAppView(View):
    def get(self, request):
        print (os.path.join(settings.REACT_APP_DIR, 'build', 'index.html'))
        try:
            with open(os.path.join(settings.REACT_APP_DIR, 'build', 'index.html')) as f:
                return HttpResponse(f.read())
        except FileNotFoundError:
            logging.exception('Production build of app not found')
            return HttpResponse(status=501)

后端: urls.py

from django.conf.urls import include, url
from rest_framework import routers
from backend import views

router = routers.DefaultRouter()

urlpatterns = [
    url(r'^api/', include(router.urls)),
    url(r'^api/photos/$', views.PhotoList.as_view()),
]

您試圖隱藏客戶端數據,這些數據(出於顯而易見的原因)駐留在客戶端中。
所以你不能真正掩蓋它。
您可以強制用戶使用其憑據登錄,這就是使用用戶名和密碼進行身份驗證的方式。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM