1

@js在 Rocket Chat 上询问,当运行 eWallet 服务器的dockerized 版本并向/admin/api/login端点发出请求时,FunctionClauseError会引发如下:

Request: POST /admin/api/login
** (exit) an exception was raised:
    ** (FunctionClauseError) no function clause matching in Base.url_decode64/2
        (elixir) lib/base.ex:482: Base.url_decode64(nil, [padding: false])
        (salty) lib/salty/utils.ex:18: Salty.Utils.decode_key/2
        (salty) lib/salty/secret_box.ex:53: Salty.SecretBox.decrypt/1
        (cloak) lib/cloak.ex:170: anonymous fn/3 in Cloak.decrypt/1
        (elixir) lib/enum.ex:1899: Enum."-reduce/3-lists^foldl/2-0-"/3
        (cloak) lib/cloak.ex:164: Cloak.decrypt/1
        (cloak) lib/cloak/types/encrypted_map_field.ex:26: Cloak.EncryptedMapField.load/1
        (ecto) lib/ecto/type.ex:647: Ecto.Type.process_loaders/3

运行vagrant 版本时似乎不会发生这种情况。

可以做些什么来解决这个问题?

4

1 回答 1

1

TLDR:取决于您实际运行的环境:

  1. devenvironment:dev通过设置环境变量强制实例作为环境运行ENV=dev

  2. prod环境:生成您自己的加密密钥并将其配置到环境变量中:

    EWALLET_SECRET_KEY=<your_secret_key>
    LOCAL_LEDGER_SECRET_KEY=<your_secret_key>
    

长版:

这个问题很难调查。它涉及知道电子钱包使用Cloak加密/解密数据库的信息。

Cloak 需要配置一个密码模块,在本例中为Salty.SecretBox.Cloak. 它具有以下解密代码:

# deps/salty/lib/salty/secret_box_cloak.ex

def decrypt(<<tag::binary-1, ciphertext::binary>>) do
  config = Salty.Utils.get_config(:cloak, @module, tag)
  Salty.SecretBox.decrypt(
    %{
      key: config.key,
      payload: ciphertext
    }
  )
end

注意这一行config = Salty.Utils.get_config(:cloak, @module, tag),它调用Salty.Utils.get_config/3以获取加密/解密密钥:

# deps/salty/lib/salty/utils.ex

def get_config(app, module, tag) do
  Application.get_env(app, module)
  |> Keyword.get(:keys)
  |> Enum.find(fn(key) -> key.tag == tag end)
end

现在,如果您查看我们的配置文件。虽然dev环境已预先配置了密钥,但您会在prodenvironment 中看到,系统将从环境变量中提取密钥EWALLET_SECRET_KEY

# apps/ewallet_db/config/prod.exs

key = System.get_env("EWALLET_SECRET_KEY")

config :cloak, Salty.SecretBox.Cloak,
       tag: "SBX",
       default: true,
       keys: [%{tag: <<1>>, key: key, default: true}]

因此,根据您打算使用的环境,解决方案是:

  1. dev环境: docker 映像设置为运行为prod. 您可以通过设置环境变量来覆盖它ENV=dev

  2. prod环境:生成您自己的加密密钥并将其配置到环境变量中:

    EWALLET_SECRET_KEY=<your_secret_key>
    LOCAL_LEDGER_SECRET_KEY=<your_secret_key>
    
于 2018-04-24T03:04:32.377 回答