????????Fetch API:現代瀏覽器內置的用于發送 HTTP 請求的 API,Bearer Token:一種基于令牌的身份驗證方案,常用于 JWT 認證,localStorage:瀏覽器提供的持久化存儲方案,用于在客戶端存儲數據。
? ? ? ? token是我們前端獲取后端數據的令牌,
// 登錄函數 - 調用真實后端API
async function loginUser(username, password) {try {const response = await fetch(`${API_URL}/auth/login`, {method: 'POST',headers: {'Content-Type': 'application/json'},body: JSON.stringify({username: username,password: password})});// 檢查響應狀態if (!response.ok) {const errorData = await response.json();throw new Error(errorData.message || '登錄失敗');}// 解析響應數據const data = await response.json();// 從響應中獲取token(后端返回的token字段)const token = data.token;// 將token存入localStoragelocalStorage.setItem('authToken', token);return token;} catch (error) {console.error('登錄錯誤:', error);throw error;}
}
? ? ? ? 我們通過輸入的賬戶密碼,從前端表格中獲取,然后在這個登錄函數中參數是我們輸入的賬戶密碼,然后我們通過fetch我們的后端發送請求,通過我們的賬戶密碼來驗證,后端對應的路由上的方法接受賬戶密碼后生成我們賬戶專屬的token,方便我們查看我們自己賬戶的數據,然后用localStorage.setItem來保存我們用戶的token。這函數是通過我們的登錄的賬戶密碼向后端申請我們賬戶的token,方便我們調用后端數據。有token才能訪問加密數據。
????????
// 獲取受保護數據 - 使用Bearer Token
async function getProtectedData() {// 從localStorage獲取tokenconst token = localStorage.getItem('authToken');if (!token) {throw new Error('未找到Token,請先登錄');}try {const response = await fetch(`${API_URL}/protected/data`, {headers: {'Authorization': `Bearer ${token}`}});// 檢查Token是否有效if (response.status === 401) {// Token無效或過期localStorage.removeItem('authToken');throw new Error('Token已過期,請重新登錄');}if (!response.ok) {throw new Error('獲取數據失敗');}return await response.json();} catch (error) {console.error('請求錯誤:', error);throw error;}
}
? ? ? ? 這是我們通過loginuser函數獲取token后就可以通過const response = await fetch(`${API_URL}/protected/data`, { headers: { 'Authorization': `Bearer ${token}` } });直接訪問后端api然后獲取加密數據了,比如我們的賬戶個人信息,我們可以在很多地方使用token。
????????
// 在登錄按鈕事件中使用
loginBtn.addEventListener('click', async () => {const username = usernameInput.value;const password = passwordInput.value;try {// 調用真實后端APIconst token = await loginUser(username, password);// 更新UI顯示tokenDisplay.innerHTML = `<strong>獲取的Token:</strong> ${token}`;showResponse('登錄成功!Token已存儲');} catch (error) {showResponse(`登錄失敗: ${error.message}`, 'error');}
});
? ? ? ? 我們在登錄按鈕點擊登錄的時候添加事件,看我們的后端數據庫是否存在我們的賬戶密碼,如果有對應的token說明賬戶密碼存在,如果報錯沒找到,就登錄失敗。也就是如果登錄成功順便拿我們的token令牌。
????????
// 在獲取受保護數據按鈕中使用
getProtectedDataBtn.addEventListener('click', async () => {try {// 使用Bearer Token獲取數據const data = await getProtectedData();showResponse(`受保護數據: ${JSON.stringify(data, null, 2)}`);} catch (error) {showResponse(`獲取失敗: ${error.message}`, 'error');}
});
????????
// 模擬受保護的API調用function simulateProtectedApiCall(token) {// 驗證token格式if (!token || token.split('.').length !== 3) {throw new Error('Invalid token');}// 模擬API響應return {id: 1,userId: 1,title: "受保護的數據",body: "這是一個需要有效Bearer Token才能訪問的數據示例。",accessTime: new Date().toISOString()};}
? ? ? ? 這段是函數通過前面登錄拿到的token之后,通過判斷token的格式,如果token確實是我們設置的格式,也就是說token是對的,我們就返回我們的加密數據。然后點擊按鈕調用這個函數,就可以顯示出我們的加密數據了,和我們在網站登錄后查看個人信息一樣。
????????
// 后端示例(Node.js/Express)
const express = require('express');
const jwt = require('jsonwebtoken');
const app = express();app.use(express.json());// 登錄端點
app.post('/auth/login', (req, res) => {const { username, password } = req.body;// 1. 驗證用戶憑證(實際應查詢數據庫)if (username !== 'demo_user' || password !== 'demo_password') {return res.status(401).json({ message: '無效憑證' });}// 2. 生成JWT Tokenconst token = jwt.sign({ userId: '123', username: 'demo_user' }, // 負載(payload)'YOUR_SECRET_KEY', // 密鑰{ expiresIn: '1h' } // 有效期);// 3. 返回Token給前端res.json({ token });
});// 受保護的數據端點
app.get('/protected/data', (req, res) => {// 1. 獲取Authorization頭const authHeader = req.headers.authorization;if (!authHeader || !authHeader.startsWith('Bearer ')) {return res.status(401).json({ message: '缺少Token' });}const token = authHeader.split(' ')[1];try {// 2. 驗證Tokenconst decoded = jwt.verify(token, 'YOUR_SECRET_KEY');// 3. 返回受保護數據res.json({message: '歡迎訪問受保護數據',user: decoded.username,protectedData: [/* 敏感數據 */]});} catch (err) {return res.status(401).json({ message: '無效Token' });}
});
? ? ? ? 這是后端代碼部分。前面的app.post是login發送的請求,通過接受前端發來的賬戶密碼,我們去數據庫中查詢是否存在,然后驗證通過 后生成專屬的token密鑰返回給前端,前端就可以拿著token密鑰來訪問保護數據了。
? ? ? ? 后面的get接口,是我們在點擊顯示保護數據按鈕之后,我們函數體首先拿到我們登錄后存取的localStorge.setItem(token),然后在請求頭中'Authorization': `Bearer ${token}`加上這個來告訴后端我們有token可以獲取加密數據,然后點擊按鈕發送后端app.get路由,后端驗證發送的token是否和后端的一致,一致則返回json響應體里面是受保護的數據,然后前端在發送命令后修改文本為響應體返回來的數據文本,這個過程就實現了。
? ? ? ? 這是登錄的時候我們通過token,以及fetch實現了前后端數據的流動,也就是登錄的時候驗證并且加載出我們的個人信息,還有相關的數據通過get獲取都需要token來驗證是否可以獲取,然后記住通過localStorge.getItem,localStorge.setItem來存儲token。