
如何在 Python 和 Flask 中使用 IP API 查找地理位置?
現在想象一下,如果您作為用戶可以與朋友分享購物車中的商品。這將為您的“確認訂單”頁面生成一個可共享的 URL,其中經過身份驗證的用戶只能查看數據而不能修改數據。聽起來很酷。但是,一旦加載此頁面,您就會訪問 API 端點,該端點還會檢索該用戶的信用卡詳細信息。攻擊者可能會竊取此信息,從而對該用戶造成潛在損害。
防止過度數據泄露的最直接方法是重構 REST API 端點。如果您知道您的 Web 服務正在發送前端不需要的敏感數據,則需要在后端查詢中過濾這些數據。這實際上有兩個目的:防止 API 泄??露不需要的敏感數據并優化數據庫查詢。
但是,第一種解決方案純粹是服務器端的。如果您使用的是第三方 Web 服務,而您無法對其進行太多控制,該怎么辦?如何防止基于前端的方法導致過度數據泄露?
您可以使用基于 GraphQL 的 API,而不是使用 REST API。GraphQL 是一種 API 架構,它使前端可以完全控制所需的數據。因此,現在您可以使用這種方法在前端僅請求非敏感數據。讓我們看看如何使用 GraphQL 來防止 React 應用程序中的過度獲取。?
第一步,我們繼續通過運行以下命令創建一個新的 React 應用程序:
npx create-react-app react-excessive-data-exposure-app
這應該為我們創建一個全新的 React 項目。接下來,繼續編輯App.js文件的內容,如下所示:
import './App.css';
function App() {
return (
<divclassName="App">
<headerclassName="App-header">
<h1>React Excessive Data Exposure with GraphQL</h1>
</header>
</div>
);
}
export default App;
現在讓我們在本地運行 React 應用程序。為此,您需要在根目錄中運行以下命令:
npm start
然后如果你訪問“http://localhost:3000”,你應該會看到以下頁面:
為了演示如何使用 GraphQL 克服過度數據暴露問題,我們首先需要一個 GraphQL 服務器或 API。為了簡單起見,我們不會從頭開始創建自己的 GraphQL API 或服務器。相反,我們將在線使用虛擬模擬 GraphQL API 來快速啟動。然后,我們可以從上一節中創建的 React 應用與此 GraphQL API 進行通信,以了解如何防止在前端過度獲取數據。
為此,我們將使用GraphQLZero,這是一個免費的虛擬在線 GraphQL API。讓我們了解一下此 API 的用例和示例。我們可以使用此工具通過 GraphQL 游樂場直觀地測試 API、請求和響應結構。在左側,您將看到一個可編輯部分。我們可以在這里編寫 GraphQL 查詢。
將以下查詢添加到此部分:
query {
user(id: 1) {
id
username
email
address {
geo {
lat
lng
}
}
}
}
然后點擊中間的 大播放按鈕。這將在右側部分顯示 JSON 響應:
太棒了!現在我們將通過 React 應用與此 GraphQL API 進行通信。那就開始吧。
在App.js中,我們首先從 React 導入useState鉤子,以便存儲從 API 調用獲得的數據。我們還將導入useEffect鉤子,以便我們可以使用鉤子中的componentDidMount生命周期等效項在頁面加載后立即進行 API 調用。
import {useEffect, useState} from 'react';
接下來,我們將利用useState鉤子創建一個狀態變量來存儲 API 的數據:
const [userData,setUserData]=useState();
之后,我們將在App組件內創建一個局部變量來保存 GraphQL API 的查詢。它是一個簡單的字符串,包含我們之前測試的精確查詢,如下所示:
const QUERY=
{<br> user(id: 1) {<br> id<br> username<br> email<br> address {<br> geo {<br> lat<br> lng<br> }<br> }<br> }<br> }
之后,我們將創建一個useEffect,并在回調函數內部編寫代碼,使用 JavaScript 的 Fetch API 向我們的模擬服務器創建 GraphQL API 請求。如下所示:
useEffect(()=>{
fetch("https://graphqlzero.almansi.me/api", {
"method": "POST",
"headers": { "content-type": "application/json" },
"body": JSON.stringify({
query: QUERY
})
}).then(res => res.json())
.then(data=>setUserData(data.data.user))
},[])
由于我們必須傳遞 QUERY 對象,因此每個 GraphQL API 都是一個 POST 請求,這就是為什么上述代碼中的方法為 POST。然后,在請求的正文部分,我們以 JSON 字符串的形式發送 API 調用的查詢。最后,我們處理兩個.then回調以將響應轉換為 JSON,然后將其存儲在我們的狀態變量中。
接下來,我們將在App.js文件中顯示這些數據:
<div className="App">
<header className="App-header">
<h1>React Excessive Data Exposure with GraphQL</h1>
<div className='data'>
<div>Username: <span>{userData?.username}</span> </div>
<br/>
<div>User ID: <span>{userData?.id}</span> </div>
<br/>
<div>Email: <span>{userData?.email}</span> </div>
</div>
</header>
</div>
請注意,我們只對用戶名、ID 和電子郵件感興趣。因此,我們從 API 中提取這些數據,然后將它們呈現在 DOM 上。完成此操作后,您的 React 應用應如下所示:
這很酷。但是讓我們檢查一下瀏覽器網絡選項卡中的 API 調用。
如果您注意到,我們僅使用電子郵件、用戶名和 ID 等一些信息,但我們還會在響應中獲取用戶的地址。顯然,我們在前端的數據使用范圍過廣。
如果這些數據被攻擊者泄露,可能會導致過度的數據泄露。那么我們該如何預防呢?
如果我們使用的是 REST API,那么通過純前端解決方案來解決這個問題是不可能的。尤其是在這種情況下,由于我們使用的是第三方 API,我們無法控制 API 的結構、它發送的數據等。幸運的是,我們正在使用 GraphQL API,其中前端可以控制它想要從請求中獲取的數據。
因此,我們需要做的就是更新查詢。更新后的查詢如下所示:
const QUERY=
{<br> user(id: 1) {<br> id<br> username<br> email<br> }<br> }
現在讓我們看看從 API 返回了什么數據:
現在我們只會得到用戶 ID、用戶名和電子郵件。太棒了!我們已防止不必要的和潛在的敏感信息在前端暴露。
我希望我能夠幫助您了解過度數據暴露是什么以及如何在 React 應用程序中防止這種情況。如果您使用的是基于 REST 的后端架構,那么解決這個問題的正確方法是重構后端 API,使其僅返回所需的數據。下次見!
文章來源:React Excessive Data Exposure: Examples and Prevention