You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在本地运行网站时不使用Local Storage存储Amazon Cognito用户凭证?

Fixing Amazon Cognito JS SDK Storage Issues with file:// Protocol

Great question! I’ve run into this exact problem when testing Cognito integrations locally using the file:// protocol—modern browsers restrict LocalStorage access for local files, which breaks the SDK’s default behavior. The good news is the Cognito JS SDK explicitly supports custom storage implementations, and it’s straightforward to set up. Here’s how to do it:

1. What the SDK Needs from a Storage Object

The SDK expects your custom storage to match the Web Storage API interface, meaning it just needs four core methods:

  • getItem(key): Retrieve a value by its key
  • setItem(key, value): Store a value under a specific key
  • removeItem(key): Delete a value by its key
  • clear(): Wipe all stored values

2. Custom Storage Implementation Options

Option 1: Switch to SessionStorage (If It Works for Your Case)

In some browsers, SessionStorage is still accessible under file://. If that’s the case for you, you can just pass it directly to the SDK:

// Initialize your Cognito User Pool with sessionStorage instead of localStorage
const poolData = {
  UserPoolId: 'YOUR_USER_POOL_ID',
  ClientId: 'YOUR_CLIENT_ID',
  storage: sessionStorage // Replace default localStorage here
};

const userPool = new AmazonCognitoIdentity.CognitoUserPool(poolData);

Option 2: In-Memory Storage (Temporary Debugging Solution)

If SessionStorage is also blocked, an in-memory storage object works for local testing (note: credentials will be lost when you refresh the page):

// Create a simple in-memory storage object
const memoryStorage = {
  _store: {},
  getItem(key) {
    return this._store[key] || null;
  },
  setItem(key, value) {
    this._store[key] = value;
  },
  removeItem(key) {
    delete this._store[key];
  },
  clear() {
    this._store = {};
  }
};

// Pass it to your User Pool initialization
const poolData = {
  UserPoolId: 'YOUR_USER_POOL_ID',
  ClientId: 'YOUR_CLIENT_ID',
  storage: memoryStorage
};

const userPool = new AmazonCognitoIdentity.CognitoUserPool(poolData);

Option 3: IndexedDB (Persistent Local Storage for file://)

If you need persistent storage (so credentials survive page refreshes), IndexedDB is a solid choice—it’s supported in most browsers even under file://. Here’s a wrapped implementation that fits the SDK’s requirements:

// Custom IndexedDB storage class for Cognito
class CognitoIndexedDBStorage {
  constructor(dbName = 'CognitoLocalStore', storeName = 'userCredentials') {
    this.dbName = dbName;
    this.storeName = storeName;
    this.db = null;
    // Initialize the DB on class creation
    this._initDB();
  }

  // Private method to set up the IndexedDB instance
  _initDB() {
    return new Promise((resolve, reject) => {
      const request = indexedDB.open(this.dbName, 1);
      
      request.onupgradeneeded = (event) => {
        const db = event.target.result;
        // Create the object store if it doesn't exist
        if (!db.objectStoreNames.contains(this.storeName)) {
          db.createObjectStore(this.storeName);
        }
      };

      request.onsuccess = (event) => {
        this.db = event.target.result;
        resolve();
      };

      request.onerror = (event) => {
        console.error('IndexedDB initialization failed:', event.target.error);
        reject(event.target.error);
      };
    });
  }

  // Get a value by key
  async getItem(key) {
    await this._initDB();
    return new Promise((resolve) => {
      const transaction = this.db.transaction(this.storeName, 'readonly');
      const store = transaction.objectStore(this.storeName);
      const request = store.get(key);

      request.onsuccess = () => resolve(request.result);
      request.onerror = () => resolve(null);
    });
  }

  // Store a key-value pair
  async setItem(key, value) {
    await this._initDB();
    return new Promise((resolve) => {
      const transaction = this.db.transaction(this.storeName, 'readwrite');
      const store = transaction.objectStore(this.storeName);
      const request = store.put(value, key);

      request.onsuccess = () => resolve();
      request.onerror = () => resolve();
    });
  }

  // Delete a value by key
  async removeItem(key) {
    await this._initDB();
    return new Promise((resolve) => {
      const transaction = this.db.transaction(this.storeName, 'readwrite');
      const store = transaction.objectStore(this.storeName);
      const request = store.delete(key);

      request.onsuccess = () => resolve();
      request.onerror = () => resolve();
    });
  }

  // Clear all stored values
  async clear() {
    await this._initDB();
    return new Promise((resolve) => {
      const transaction = this.db.transaction(this.storeName, 'readwrite');
      const store = transaction.objectStore(this.storeName);
      const request = store.clear();

      request.onsuccess = () => resolve();
      request.onerror = () => resolve();
    });
  }
}

// Usage example
const cognitoStorage = new CognitoIndexedDBStorage();
const poolData = {
  UserPoolId: 'YOUR_USER_POOL_ID',
  ClientId: 'YOUR_CLIENT_ID',
  storage: cognitoStorage
};

const userPool = new AmazonCognitoIdentity.CognitoUserPool(poolData);

3. Key Notes

  • In-memory storage is only for local testing—don’t use it in production, as users will lose their session on every page refresh.
  • IndexedDB is asynchronous, so the wrapper above uses Promises to ensure the SDK can interact with it correctly.
  • Browser restrictions for file:// can vary, so test each option to see which works best for your setup. For production, always serve your app over HTTP/HTTPS to use standard LocalStorage without issues.

内容的提问来源于stack exchange,提问作者Berry Blue

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 04:01:49