【问题标题】:How to store Msal node token cache in database and Stop clearing cache on app restart如何将 Msal 节点令牌缓存存储在数据库中并在应用重新启动时停止清除缓存
【发布时间】:2021-10-08 07:55:23
【问题描述】:

我正在从我的节点应用程序调用图形 API。为此,我创建了机密客户端应用程序。我想将令牌缓存存储在数据库(postgres)中。我该怎么做?

此外,每当我重新启动节点应用程序时,msal 会清除其令牌缓存,是否有任何方法可以阻止 msal 节点在应用程序重新启动时清除其缓存?

目前的实现如下:

const fs = require('fs');
const msal = require('@azure/msal-node');
const cachePath = 'cache.json';
const beforeCacheAccess = async(cacheContext) => {
    cacheContext.tokenCache.deserialize(fs.readFile(cachePath, "utf-8", (err, d) => {
        //console.log("errror", err, d)

    }));
};

const afterCacheAccess = async(cacheContext) => {
    if (cacheContext.cacheHasChanged) {
        fs.writeFile(cachePath, cacheContext.tokenCache.serialize(), (err) => {
            //console.log("errror", err)
        });
    }
};

// Cache Plugin
const cachePlugin = {
    beforeCacheAccess,
    afterCacheAccess
};

const msalConfig = {
    auth: {
        clientId: config.MS_CLIENT_ID,
        authority: config.AAD_ENDPOINT + 'consumers', //config.TENANT_ID,
        clientSecret: config.MS_CLIENT_SECRET,
    },
    cache: {
        cachePlugin // your implementation of cache plugin
    },
};
const scopes = ["Mail.ReadWrite", "Mail.Send"]

const cca = new msal.ConfidentialClientApplication(msalConfig);

【问题讨论】:

    标签: node.js postgresql msal msal.js


    【解决方案1】:

    具体实现取决于您要使用的数据库,但粗略地描述您必须在示例中实现对数据库而不是文件系统的调用:

    ...
    const beforeCacheAccess = async(cacheContext) => {
    
        let dataFromDb = someMethodThatReadsTheCacheFromDb()
    
        if(dataFromDb == null) {
          // didn't find previously existing data, so store current cache regardless if empty or not
          someMethodThatStoresCacheToDb(cacheContext.tokenCache.serialize())
        } else {
          // found cache data, restore into the cache context
          cacheContext.tokenCache.deserialize(dataFromDb)
        }
    };
    
    const afterCacheAccess = async(cacheContext) => {
        if (cacheContext.cacheHasChanged) {
            // store changes to db
            someMethodThatStoresCacheToDb(cacheContext.tokenCache.serialize())
        }
    };
    ...
    

    但是请注意,这不能很好地扩展,因为当前缓存上下文会将所有客户端的令牌存储到相同的序列化字符串中。

    根据这个讨论评论,有一个用于标准化插入分布式缓存的路线图项目,但 atm.没有正式的实施。 https://github.com/AzureAD/microsoft-authentication-library-for-js/issues/2828#issuecomment-797696193

    还建议通读此讨论(不是特定于 node.js,但与 MSAL 中的令牌缓存有关): https://github.com/AzureAD/microsoft-authentication-library-for-python/issues/98,特别是这条评论: https://github.com/AzureAD/microsoft-authentication-library-for-python/issues/98#issuecomment-535754922

    它解释说,MSAL 中的缓存系统最初是为客户端应用程序而非 Web 应用程序而构建的,这意味着需要将有限的 nr 个帐户存储在缓存中,因为其目的是缓存运行例如用户电话。因此缓存不能很好地扩展,相反,如果您需要支持许多用户,您应该为每个用户创建一个缓存,然后为每个请求使用用户特定的缓存。例如。序列化缓存并使用用户特定的键将其存储在数据库中,您可以使用该键在以后的请求中获取和恢复缓存。

    至于在应用程序启动期间清除缓存我不知道。我假设如果缓存像您的示例插件实现所建议的那样写入文件系统,那么当 msal 第一次尝试访问缓存时,它应该从那里恢复。所以我首先要验证缓存是否真的被写入你的cachePath。如果由于某种原因,当您启动应用程序时您的 cachePath 被重置(例如,如果您碰巧使用 webpack 运行您的代码并且缓存存储在构建文件夹中,该文件夹在每次构建时都会被删除),那么这也可以解释重置。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-07-03
      • 2019-04-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-09-01
      • 2018-11-24
      相关资源
      最近更新 更多