【发布时间】:2019-03-24 13:00:12
【问题描述】:
目标:支持根据某些安全性或已定义的用户角色要求动态加载 Javascript 模块,这样即使在开发工具中识别了模块的名称,也无法通过控制台。
JavaScript 模块可以轻松上传到 Firebase (#AskFirebase) 等云存储服务,并且可以根据自定义声明或类似测试的存在使用 Firebase 云函数firebase.functions().httpsCallable("ghost"); 有条件地检索代码。
export const ghost = functions.https.onCall(async (data, context) => {
if (! context.auth.token.restrictedAccess === true) {
throw new functions.https.HttpsError('failed-precondition', 'The function must be called while authenticated.');
}
const storage = new Storage();
const bucketName = 'bucket-name.appspot.com';
const srcFilename = 'RestrictedChunk.chunk.js';
// Downloads the file
const response = await storage
.bucket(bucketName)
.file(srcFilename).download();
const code = String.fromCharCode.apply(String, response[0])
return {source: code};
})
最后,我想做什么……
...就是拿一个 webpack 的 React 组件,放到云端,服务器端安全检查后有条件的下载到客户端,import() 到用户的客户端环境并渲染它。
将 Javascript 存储在云中并有条件地下载到客户端很容易。一旦我在客户端中获得了 webpack 的代码,我可以使用 Function(downloadedRestrictedComponent) 将其添加到用户的环境中,就像使用 import('./RestrictedComponent') 一样,但我不知道如何从组件,所以我可以实际渲染这个东西。
import(pathToComponent) 返回加载的模块,据我所知,没有选项可以传递import() 字符串或流,只是模块的路径。 Function(downloadedComponent) 会将下载的代码添加到客户端环境中,但我不知道如何访问模块的导出以呈现动态加载的 React 组件。
有没有办法从下载的流中动态导入 Javascript 模块?
编辑添加:感谢您的回复。不熟悉 Blob 和 URL.createObjectURL 的细微差别。知道为什么找不到吗?
const ghost = firebase.functions().httpsCallable("ghost");
const LoadableRestricted = Loadable({
// loader: () => import(/* webpackChunkName: "Restricted" */ "./Restricted"),
loader: async () => {
const ghostContents = await ghost();
console.log(ghostContents);
const myBlob = new Blob([ghostContents.data.source], {
type: "application/javascript"
});
console.log(myBlob);
const myURL = URL.createObjectURL(myBlob);
console.log(myURL);
return import(myURL);
},
render(loaded, props) {
console.log(loaded);
let Component = loaded.Restricted;
return <Component {...props} />;
},
loading: Loading,
delay: 2000
});
【问题讨论】:
-
您有没有找到自己喜欢的完整解决方案?
-
Shaz 或其他任何人:对这个问题有完整的解决方案吗? 我想分配 +500 赏金,但没有人加紧,明天将在我的控制之外到期。
-
@kjhughes 如果我理解正确,您将文件下载到目录
./RestrictedComponent.js,如果用户已通过身份验证,导入该组件?是这样,你考虑过React.lazy吗? -
@radihuq:
React.lazy可能有助于动态导入方面(谢谢),但它本身并不能阻止未经身份验证的用户通过从端点获取受限 JavaScript 从服务器检索受限制的 JavaScript。客户端 UI 检查。 -
@kjhughes 啊,好吧,我明白了。也许服务器端渲染是解决方案,或者something like this,但我对此没有太多经验。祝你好运!
标签: javascript reactjs firebase webpack react-loadable