[英]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 的問題,但來自數據庫的數據並未顯示在網站上。
我的問題如下:
任何幫助深表感謝!
更新:解決方案
根據@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.