Electron應用中獲取設備唯一ID和系統信息

讓我創建一篇關于如何在Electron應用中獲取設備唯一ID和系統信息,并在登錄時使用這些信息的博客文章。我將確保步驟明確、條理清晰,適合初學者和有經驗的開發者。

這篇博客應包含以下部分:

  1. 介紹 - 為什么需要獲取設備信息
  2. 前提條件和安裝依賴
  3. 主進程(main.js)配置 - 添加IPC處理程序
  4. 預加載腳本(preload.js)配置 - 暴露安全API
  5. 渲染進程(前端Vue組件)使用
  6. 調試技巧和常見問題
  7. 安全和隱私考慮
  8. 總結和進一步閱讀

這樣的結構應該能全面覆蓋這個功能的實現并幫助讀者理解每個部分的作用。

在Electron應用中獲取設備唯一ID和系統信息

簡介

在現代應用程序開發中,獲取設備唯一標識和系統信息是一項常見需求,尤其對于需要設備識別、登錄驗證和用戶行為分析的應用。本文將詳細講解如何在Electron應用中實現設備信息獲取功能,并將其與登錄流程集成。

為什么需要獲取設備信息?

  • 設備識別:跟蹤和識別用戶的不同設備
  • 安全驗證:增強賬號安全,防止未授權登錄
  • 數據分析:了解用戶設備分布和使用環境
  • 功能適配:根據系統環境提供定制化功能

前提條件

  • Node.js 和 npm 已安裝
  • 基本的Electron應用結構
  • Vue.js前端框架(本文使用Vue 3)

實現步驟

1. 安裝必要依賴

首先,我們需要安裝node-machine-id庫來獲取設備唯一ID:

# 在項目的client目錄下執行
cd client
npm install node-machine-id --save

2. 配置主進程(main.js)

在Electron的主進程文件中,添加獲取系統信息和設備ID的IPC處理函數:

// client/electron/main.jsconst { app, BrowserWindow, ipcMain } = require('electron')
const path = require('path')
const os = require('os')
const { machineIdSync } = require('node-machine-id')// 其他現有代碼...// 添加獲取系統信息的處理函數
ipcMain.handle('get-system-info', () => {try {const systemInfo = {platform: process.platform,  // 'win32', 'darwin', 'linux'等arch: process.arch,          // 'x64', 'arm64'等osName: os.type(),           // 操作系統類型osVersion: os.release(),     // 操作系統版本hostname: os.hostname(),     // 主機名totalMem: os.totalmem(),     // 總內存(字節)cpuCores: os.cpus().length   // CPU核心數};return systemInfo;} catch (error) {console.error('獲取系統信息失敗:', error);return {platform: 'unknown',arch: 'unknown',osName: 'unknown',osVersion: 'unknown',hostname: 'unknown'};}
});// 添加獲取設備唯一ID的處理函數
ipcMain.handle('get-machine-id', () => {try {// 使用node-machine-id庫獲取系統唯一IDconst machineId = machineIdSync(true);console.log('生成的machineId:', machineId);return machineId;} catch (error) {console.error('獲取設備ID失敗:', error);// 生成一個隨機ID作為后備方案const fallbackId = 'device-' + Math.random().toString(36).substring(2, 15);return fallbackId;}
});

3. 創建預加載腳本(preload.js)

預加載腳本是連接Electron主進程和渲染進程的橋梁,通過它我們可以安全地暴露主進程API給渲染進程:

// client/preload.jsconst { contextBridge, ipcRenderer } = require('electron');// 調試信息
console.log('preload.js 正在加載...');function logToConsole(message) {console.log(`[preload] ${message}`);
}// 暴露API給渲染進程
contextBridge.exposeInMainWorld('electron', {// 獲取系統信息 - 返回PromisegetSystemInfo: async () => {logToConsole('調用getSystemInfo');try {const result = await ipcRenderer.invoke('get-system-info');logToConsole(`getSystemInfo結果: ${JSON.stringify(result)}`);return result;} catch (error) {logToConsole(`getSystemInfo錯誤: ${error.message}`);throw error;}},// 獲取設備ID - 返回PromisegetMachineId: async () => {logToConsole('調用getMachineId');try {const result = await ipcRenderer.invoke('get-machine-id');logToConsole(`getMachineId結果: ${result}`);return result;} catch (error) {logToConsole(`getMachineId錯誤: ${error.message}`);throw error;}},// 測試API可用性 - 直接返回值testAPI: () => {logToConsole('testAPI被調用');return '測試API可用';},// 應用版本 - 直接返回值getVersion: () => {return '1.0.0';}
});console.log('preload.js 已完成加載');

4. 配置BrowserWindow,確保使用preload.js

main.js中創建窗口時,確保正確配置了preload腳本:

function createWindow() {mainWindow = new BrowserWindow({width: 1200,height: 800,// 其他窗口配置...webPreferences: {nodeIntegration: false,contextIsolation: true,webSecurity: false,preload: path.join(__dirname, '../preload.js')  // 預加載腳本路徑}});// 加載應用...
}

5. 在Vue組件中使用設備信息

在登錄組件(如LoginView.vue)中,添加獲取設備信息的功能:

// client/src/views/LoginView.vue<script setup>
import { ref, onMounted } from 'vue';
import { useRouter } from 'vue-router';
import { useAppStore } from '@/stores/useAppStore';const router = useRouter();
const appStore = useAppStore();// 表單數據
const username = ref('admin');
const password = ref('admin');
const remember = ref(false);
const errorMsg = ref('');
const isLoading = ref(false);// 設備信息
const deviceId = ref('');
const systemInfo = ref(null);// 檢查API是否可用
const checkElectronAPI = () => {console.log('測試Electron API是否可用...');if (window.electron) {console.log('window.electron 對象存在');// 檢查異步函數是否存在console.log('getSystemInfo 存在?', typeof window.electron.getSystemInfo === 'function');console.log('getMachineId 存在?', typeof window.electron.getMachineId === 'function');} else {console.log('window.electron 對象不存在,可能在瀏覽器環境或preload.js未加載');}
};// 獲取系統信息和設備ID
const getSystemInfo = async () => {console.log('開始獲取系統信息...');try {// 檢查electron對象是否可用if (typeof window.electron !== 'undefined') {console.log('檢測到Electron環境');try {// 獲取系統信息console.log('正在調用getSystemInfo...');const info = await window.electron.getSystemInfo();console.log('獲取到系統信息:', info);systemInfo.value = info;// 獲取設備IDconsole.log('正在調用getMachineId...');const id = await window.electron.getMachineId();console.log('獲取到設備ID:', id);deviceId.value = id;// 保存到localStoragelocalStorage.setItem('system_info', JSON.stringify(info));localStorage.setItem('device_id', id);return true;} catch (err) {console.error('調用Electron API出錯:', err);return false;}} else {console.log('非Electron環境,使用Web備選方案');// Web環境下的備選方案if (!localStorage.getItem('device_id')) {const randomId = 'web-' + Math.random().toString(36).substring(2, 15);localStorage.setItem('device_id', randomId);deviceId.value = randomId;} else {deviceId.value = localStorage.getItem('device_id');}const webInfo = {platform: 'web',userAgent: navigator.userAgent,language: navigator.language};systemInfo.value = webInfo;localStorage.setItem('system_info', JSON.stringify(webInfo));return true;}} catch (error) {console.error('獲取系統信息總體失敗:', error);return false;}
};// 登錄處理函數
const handleLogin = async () => {// 表單驗證if (!username.value || !password.value) {errorMsg.value = !username.value ? '請輸入用戶名' : '請輸入密碼';return;}try {isLoading.value = true;errorMsg.value = '';// 確保有設備IDif (!deviceId.value) {console.log('登錄前獲取設備ID');await getSystemInfo();}// 組裝登錄數據const loginData = {username: username.value,password: password.value,deviceId: deviceId.value || localStorage.getItem('device_id'),systemInfo: systemInfo.value || JSON.parse(localStorage.getItem('system_info') || '{}')};// 調用登錄API  
};// 組件掛載時獲取系統信息
onMounted(() => {console.log('組件已掛載,獲取系統信息');checkElectronAPI();getSystemInfo();
});
</script>

調試技巧

使用控制臺測試API

在瀏覽器開發者工具的控制臺中,可以直接測試API:

// 檢查electron對象是否存在
console.log('window.electron 對象存在?', !!window.electron);// 測試調用API
if (window.electron) {// 測試異步APIwindow.electron.getSystemInfo().then(info => {console.log('系統信息:', info);localStorage.setItem('system_info', JSON.stringify(info));}).catch(err => {console.error('獲取系統信息失敗:', err);});window.electron.getMachineId().then(id => {console.log('設備ID:', id);localStorage.setItem('device_id', id);}).catch(err => {console.error('獲取設備ID失敗:', err);});
}

檢查localStorage

在開發者工具的Application/Storage標簽中,查看localStorage是否正確保存了設備信息:

  • system_info
  • device_id

常見問題解決

1. Cannot find module ‘node-machine-id’

確保已正確安裝依賴:

npm install node-machine-id --save

2. window.electron對象為undefined

可能的原因:

  • preload.js路徑配置錯誤
  • contextIsolation設置不正確
  • preload.js中沒有正確暴露API

解決方案:檢查BrowserWindow的webPreferences配置,確保preload路徑正確。

3. 調用API時出現"不是函數"錯誤

區分同步和異步API:

  • 同步API (如testAPI):直接調用 const result = window.electron.testAPI()
  • 異步API (如getSystemInfo):使用Promise await window.electron.getSystemInfo()

安全注意事項

  1. 不要暴露敏感API:只暴露渲染進程需要的API,遵循最小權限原則
  2. 處理異常:所有API調用都應有適當的錯誤處理
  3. 保護用戶隱私:僅收集必要的設備信息,并告知用戶
  4. 安全存儲:避免在localStorage中存儲敏感信息,考慮使用加密

總結

通過本文介紹的方法,可以在Electron應用中安全地獲取設備唯一ID和系統信息,并將其與登錄流程集成。這種方式遵循了Electron的安全最佳實踐,使用上下文隔離和預加載腳本來安全地暴露主進程API給渲染進程。

正確實現后,能夠識別用戶設備,增強安全性,并提供更好的用戶體驗。此功能對于需要設備綁定、多設備管理和用戶行為分析的應用特別有用。

參考文檔

  1. Electron安全性文檔
  2. node-machine-id庫文檔
  3. Electron上下文隔離
  4. Electron IPC通信

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/73128.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/73128.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/73128.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

【每日學點HarmonyOS Next知識】自定義對話框關閉、WaterFlow嵌套、狀態欄顏色、滾動吸附、滾動動效

1、HarmonyOS 自定義對話框自動關閉的問題&#xff1f; 啟動頁做了個隱私協議彈窗&#xff0c;autoCancel為false。UI中使用 Text() ContainerSpan() Span()組件&#xff0c;設置了點擊事件&#xff0c;點擊后使用router.pushUrl()的方法跳轉到協議頁面。點擊時&#xff0c;對…

【物聯網-WIFI】

物聯網-WIFI ■ ESP32-C3-模塊簡介■ ESP32-C3-■ ESP32-C3-■ WIFI-模組■ WIFI-■ WIFI- ■ ESP32-C3-模塊簡介 ■ ESP32-C3- ■ ESP32-C3- ■ WIFI-模組 ■ WIFI- ■ WIFI-

Xilinx ZYNQ FSBL解讀:LoadBootImage()

篇首 最近突發奇想&#xff0c;Xilinx 的集成開發環境已經很好了&#xff0c;很多必要的代碼都直接生成了&#xff0c;這給開發者帶來了巨大便利的同時&#xff0c;也讓人錯過了很多代碼的精彩&#xff0c;可能有很多人用了很多年了&#xff0c;都還無法清楚的理解其中過程。博…

LeetCode1871 跳躍游戲VII

LeetCode 跳躍游戲 IV&#xff1a;二進制字符串的跳躍問題 題目描述 給定一個下標從 0 開始的二進制字符串 s 和兩個整數 minJump 和 maxJump。初始時&#xff0c;你位于下標 0 處&#xff08;保證該位置為 0&#xff09;。你需要判斷是否能到達字符串的最后一個位置&#xf…

Burpsuite使用筆記

Burpsuite使用筆記 抓包設置代理open Browserintercept on輸入要抓包的網站回車ForwardHTTP history查看抓包數據其他瀏覽器配置burpsuite代理瀏覽器代理器插件配置打開代理同樣步驟訪問原理三級目錄抓包 設置代理 open Browser 打開內置瀏覽器 intercept on 輸入要抓包的網…

Windows 遠程桌面多端口訪問,局域網虛擬IP映射多個Windows 主機解決方案

情景 項目現場4G路由局域網中兩臺主機通過VPN連接到公司內網&#xff0c;實現遠程管理&#xff0c;要求映射兩個Windows 桌面進行管理。 目錄 情景 網絡 思路 已知 問題解決 1.客戶端通過VPN進入內網路由器配置NAT 2.使用遠程主機遠程桌面功能&#xff1a;IP端口號訪問 …

【深度學習】讀寫文件

讀寫文件 到目前為止&#xff0c;我們討論了如何處理數據&#xff0c;以及如何構建、訓練和測試深度學習模型。 然而&#xff0c;有時我們希望保存訓練的模型&#xff0c;以備將來在各種環境中使用&#xff08;比如在部署中進行預測&#xff09;。 此外&#xff0c;當運行一個…

仿Manus一

復制 ┌───────────────┐ ┌─────────────┐ │ 主界面UI │?─────?│ 會話管理模塊 │ └───────┬───────┘ └──────┬──────┘│ │▼ ▼ ┌─…

VS Code C++ 開發環境配置

VS Code 是當前非常流行的開發工具. 本文講述如何配置 VS Code 作為 C開發環境. 本文將按照如下步驟來介紹如何配置 VS Code 作為 C開發環境. 安裝編譯器安裝插件配置工作區 第一個步驟的具體操作會因為系統不同或者方案不同而有不同的選擇. 環境要求 首先需要立即 VS Code…

Flutter 學習之旅 之 flutter 不使用插件,實現簡單帶加載動畫的 LoadingToast 功能

Flutter 學習之旅 之 flutter 不使用插件&#xff0c;實現簡單帶加載動畫的 LoadingToast 功能 目錄 Flutter 學習之旅 之 flutter 不使用插件&#xff0c;實現簡單帶加載動畫的 LoadingToast 功能 一、簡單介紹 二、LoadingToast 三、簡單案例實現 四、關鍵代碼 一、簡單…

Spring (八)AOP-切面編程的使用

目錄 實現步驟&#xff1a; 1 導入AOP依賴 2 編寫切面Aspect 3 編寫通知方法 4 指定切入點表達式 5 測試AOP動態織入 圖示&#xff1a; 一 實現步驟&#xff1a; 1 導入AOP依賴 <!-- Spring Boot AOP依賴 --><dependency><groupId>org.springframewor…

開源數字人模型Heygem

一、Heygem是什么 Heygem 是硅基智能推出的開源數字人模型&#xff0c;專為 Windows 系統設計。基于先進的AI技術&#xff0c;僅需1秒視頻或1張照片&#xff0c;能在30秒內完成數字人形象和聲音克隆&#xff0c;在60秒內合成4K超高清視頻。Heygem支持多語言輸出、多表情動作&a…

uniapp開通開屏廣告后動態開啟或關閉開屏廣告

近期使用uniapp開發的APP有uniad的廣告對接&#xff0c;并且要求會員用戶不顯示包含開屏廣告在內的廣告&#xff0c;除開屏廣告外的廣告都可以通過uniapp廣告組件控制是否顯示 因uniad的開屏廣告無需代碼開發&#xff0c;經過uniad客服指點可在App.vue中的onLaunch生命周期中執…

神經網絡為什么要用 ReLU 增加非線性?

在神經網絡中使用 ReLU&#xff08;Rectified Linear Unit&#xff09; 作為激活函數的主要目的是引入非線性&#xff0c;這是神經網絡能夠學習復雜模式和解決非線性問題的關鍵。 1. 為什么需要非線性&#xff1f; 1.1 線性模型的局限性 如果神經網絡只使用線性激活函數&…

使用SSH密鑰連接本地git 和 github

目錄 配置本地SSH&#xff0c;添加到github首先查看本地是否有SSH密鑰生成SSH密鑰&#xff0c;和郵箱綁定將 SSH 密鑰添加到 ssh-agent&#xff1a;顯示本地公鑰*把下面這一串生成的公鑰存到github上* 驗證SSH配置是否成功終端跳轉到本地倉庫把http協議改為SSH&#xff08;如果…

關于AI數據分析可行性的初步評估

一、結論&#xff1a;可在部分環節嵌入&#xff0c;無法直接處理大量數據 1.非本地部署的AI應用處理非機密文件沒問題&#xff0c;內部文件要注意數據安全風險。 2.AI&#xff08;指高規格大模型&#xff09;十分適合探索性研究分析&#xff0c;對復雜報告無法全流程執行&…

矩陣分析-淺要理解(深度學習方向)

梯度分析與最優化 在深度學習的任務中&#xff0c;我們所期望的是訓練一個神經網絡&#xff0c;使得預測結果與真實標簽之間的誤差最小化&#xff0c;這可以近似看作是一個提供梯度下降等優化找到全局最優解的凸優化問題。 奇異值分解 在信息工程領域&#xff0c;對數據處理的…

使用DeepSeek+藍耘快速設計網頁簡易版《我的世界》小游戲

前言&#xff1a;如今&#xff0c;借助先進的人工智能模型與便捷的云平臺&#xff0c;即便是新手開發者&#xff0c;也能開啟創意游戲的設計之旅。DeepSeek 作為前沿的人工智能模型&#xff0c;具備強大的功能與潛力&#xff0c;而藍耘智算云平臺則為其提供了穩定高效的運行環境…

固定表頭、首列 —— uniapp、vue 項目

項目實地&#xff1a;也可以在 【微信小程序】搜索體驗&#xff1a;xny.handbook 另一個體驗項目&#xff1a;官網 一、效果展示 二、代碼展示 &#xff08;1&#xff09;html 部分 <view class"table"><view class"tr"><view class&quo…

【學習筆記】Numpy和Tensor的區別

1. NumPy 和 PyTorch Tensor 的格式對比 NumPy 使用的是 numpy.ndarray&#xff0c;而 PyTorch 使用的是 torch.Tensor&#xff0c;兩者的格式在數據存儲和計算方式上有所不同。 NumPy (numpy.ndarray) import numpy as np array np.array([[1.0, 2.0, 3.0], [4.0, 5.0, 6.…