如何使用 importmaps 将环境信息传递给 javascript 代码

Gor*_*vic 5 ruby ruby-on-rails import-maps

I\xe2\x80\x99m 使用 Rails 7 和 importmaps,并且 I\xe2\x80\x99m 尝试使 JavaScript 代码有条件地依赖于环境特定的配置。至少, I\xe2\x80\x99d 需要首先传递它是什么环境(开发、测试等),理想情况下,我\xe2\x80\x99d 喜欢传递任意 env 相关配置。

\n

我能做的是从控制器提供一个 js 文件,并在其中创建一个全局配置变量,提供我希望 js 代码可用的任何配置信息。

\n

但我\xe2\x80\x99m想知道我\xe2\x80\x99m是否缺少一些明显的\xe2\x80\x9cofficial\xe2\x80\x9d方式这样做。有吗?

\n

Gar*_*her 2

我想发布一个有关我过去如何管理此问题的架构答案,以便为所有类型的用户应用程序提供易于管理和安全的解决方案。

它与技术无关,但这种设计应该适合您的 Rails 应用程序。如果 Rails 不允许您遵循这些原则,我会避免使用 Rails 导入映射。

构建一次二进制文件

无论采用什么技术,一次性构建代码,然后在不进行任何更改的情况下将资产推广到管道中,都有很多优点。所以你到处测试完全相同的代码。如果存在错误,堆栈跟踪是相同的,依此类推:

  • 开发--> 分期--> 生产

网络二进制文件

这些天我喜欢将 Javascript 构建到捆绑包中,然后将子资源完整性标签添加到 index.html 文件中,以将资源捆绑在一起,就像我的这个演示应用程序一样:

<!DOCTYPE html>
<html lang='en'>
    <head>
        <meta charset='utf-8'>
        <meta name='viewport' content='width=device-width, initial-scale=1, shrink-to-fit=no'>

        <base href='/spa/' />
        <title>OAuth Demo App</title>

        <link rel='stylesheet' href='bootstrap.min.css?t=1649189065161' integrity='sha256-YvdLHPgkqJ8DVUxjjnGVlMMJtNimJ6dYkowFFvp4kKs='>
        <link rel='stylesheet' href='app.css?t=1649189065161' integrity='sha256-B7pu+gcFspulW4zXfgczVtPcEuZ81tZRFYeRciEzWro='>
    <body>
        <div id='root' class='container'></div>

        <script type='module' src='vendor.bundle.js?t=1649189065161' integrity='sha256-p+HJCny/HKNJXb18K7GW6jKqw4bZN2AZnUWtXJCDLT8='></script>
        <script type='module' src='app.bundle.js?t=1649189065161' integrity='sha256-WGayM6x6jt2rJ5PwBvuV+vytuDBdBOkHQoO08iCdWfM='></script>
    </body>
</html>
Run Code Online (Sandbox Code Playgroud)

生产代码点

在代码中,我有一个用于生产配置的环境对象,如下例所示。这只包含公共/非敏感数据,我不在乎黑客是否掌握了它。

export const productionConfiguration = {

    app: {
        webOrigin: 'https://web.authsamples.com',
        apiBaseUrl: 'https://tokenhandler.authsamples.com/api'
    },
    oauth: {
        oauthAgentBaseUrl: 'https://tokenhandler.authsamples.com/oauth-agent',
    }
} as Configuration;
Run Code Online (Sandbox Code Playgroud)

其他环境覆盖

在运行时,如果在不同的源中运行,我会config.json从 Web 源下载一个静态文件,其中包含环境数据:

public async get(): Promise<Configuration> {

    if (location.origin.toLowerCase() === productionConfiguration.app.webOrigin.toLowerCase()) {
        return productionConfiguration;
    }

    return this._download();
}
Run Code Online (Sandbox Code Playgroud)

这使得无需重建代码即可创建新的测试环境。我希望避免生产用户进行此下载,以便所有主要 Web 资源都绑定到 index.html 文件。

移动的

与 APK / IPA 文件中内置的生产配置一起发布的相同原理也可以在移动应用程序中使用。移动环境数据可能包含不同的信息,如我的示例应用程序所示:

{
  "app": {
    "apiBaseUrl":             "https://api.authsamples.com/api"
  },
  "oauth": {
    "authority":              "https://cognito-idp.eu-west-2.amazonaws.com/eu-west-2_qqJgVeuTn",
    "clientId":               "3pj7bd0ff8h1klhok774303dq8",
    "webBaseUrl":             "https://authsamples.com",
    "loginRedirectPath":      "/apps/basicmobileapp/postlogin.html",
    "postLogoutRedirectPath": "/apps/basicmobileapp/postlogout.html",
    "scope":                  "openid profile email https://api.authsamples.com/api/transactions_read",
    "deepLinkBaseUrl":        "https://mobile.authsamples.com",
    "customLogoutEndpoint":   "https://login.authsamples.com/logout"
  }
}
Run Code Online (Sandbox Code Playgroud)

通常的技术是有一个设置页面,可以在其中覆盖这些值,例如将应用程序指向测试环境。

保护环境数据

当然,UI 仅在用户进行身份验证后下载任何敏感环境数据,例如通过向 API 发送安全 cookie 或访问令牌。