iT邦幫忙

0

【Day 10】前端 AI 專案的資安防護:打造安全且直覺的 API Key 設定彈窗

  • 分享至 

  • xImage
  •  
一、 前言

在前幾天的文章中,我們已經順利將 Google Gemini API 串接進「AI 酒館」中。然而,在 100% 前端運行的 Vite 專案裡,使用者的 API Key 通常是存放在瀏覽器的 localStorage 中。如果缺乏良好的介面封裝與隱私遮罩,不僅使用體驗打折,也容易造成金鑰不小心曝光。

為了讓專案更具備「產品感」,今天的核心任務是實作:安全、直覺且具備錯誤提示的 API Key 設定彈窗!

二、 為什麼前端 AI 專案需要獨立的設定彈窗?
  1. 保護使用者隱私:透過密碼遮罩(Password Masking)與顯示切換按鈕,防止旁人窺看。
  2. 降低操作門檻:提供直覺的彈窗互動與官方免費申請連結,讓非技術背景玩家也能輕鬆上手。
三、 實作步驟與核心程式碼
  1. 下達 Vibe Coding 需求
    我們透過 AI 助手建立了一個模態視窗組件,並將 localStorage 的讀寫邏輯與顯示切換(Eye Toggle)封裝在內。

  2. 核心設定與遮罩邏輯實作
    前端處理金鑰狀態與密碼顯示切換的程式碼概念大致如下:

    import { useState } from 'react';
    
    export function ApiKeySettingsModal({ isOpen, onClose, onSave }) {
      const [apiKey, setApiKey] = useState(() => localStorage.getItem('gemini_api_key') || '');
      const [showKey, setShowKey] = useState(false);
    
      const handleSave = () => {
        localStorage.setItem('gemini_api_key', apiKey);
        onSave(apiKey);
        onClose();
      };
    
      if (!isOpen) return null;
    
      return (
        <div className="fixed inset-0 bg-black/60 flex items-center justify-center z-50">
          <div className="bg-zinc-900 border border-zinc-700 p-6 rounded-xl w-full max-w-md shadow-2xl">
            <h3 className="text-xl font-bold text-zinc-100 mb-4">Gemini API 設定</h3>
            <div className="relative mb-4">
              <input
                type={showKey ? 'text' : 'password'}
                value={apiKey}
                onChange={(e) => setApiKey(e.target.value)}
                placeholder="請輸入您的 Gemini API Key"
                className="w-full bg-zinc-800 border border-zinc-700 rounded-lg px-4 py-2 text-zinc-100 pr-10 focus:outline-none focus:border-amber-500"
              />
              <button
                onClick={() => setShowKey(!showKey)}
                className="absolute right-3 top-2.5 text-zinc-400 hover:text-zinc-200"
              >
                {showKey ? '隱藏' : '顯示'}
              </button>
            </div>
            <div className="flex justify-end gap-3">
              <button onClick={onClose} className="px-4 py-2 bg-zinc-800 text-zinc-300 rounded-lg">取消</button>
              <button onClick={handleSave} className="px-4 py-2 bg-amber-600 text-white rounded-lg">儲存設定</button>
            </div>
          </div>
        </div>
      );
    }
    
四、 今日心得與預告
  • 今日心得:為 API Key 加上專屬的設定彈窗與遮罩後,整個專案的完成度瞬間從「玩具級」跨入「產品級」!細節的雕琢往往是前後端分離專案成敗的關鍵。
  • 明日預告 (Day 11):【架構】對話清單管理與多話題切換!讓每個角色底下可以開創不同的聊天主題!

圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言