もんりぃ is undefined.

育児ネタとか、技術ネタとか。

Unity Package Manager で Private な Scoped Registry を登録する方法

はじめに

2019/06/11 追記

この記事にはセキュリティ的な問題があります。

より安全な方法を以下に纏めましたので、そちらをご参照ください。

monry.hatenablog.com


どうも、Unity Package Manager 大好きおじさんです。

最近は、Unity Package Manager で Private Scoped Registry を実現する方法を模索しています。

なんか全然 C# 書いてない気がしなくもないですが、気のせい…ですよね…?

背景

Unity 2019.1 の時点では Unity Package Manager が Scoped Registry に接続しに行く際に、リクエストヘッダに Authorization: Bearer <auth_token> を付けてくれません。 2020.1 で対応されるとかなんとか。)

なので、Charles を用いて「Scoped Registry にアクセスする際には必ず Authorization ヘッダを付ける」という Rewrite を行う必要があります。 勿論、別途 Proxy サーバを立てて、仲介させる手もあるのですが、どっちみち認証の上手い方法が無いため落としどころとして。

が、Unity Hub や Unity Package Manager は、Charles が介入できる通信を用いていないようで、そのままでは期待した動きを実現できませんでした。(ココよく分かっていないので、詳しい人居たら教えて欲しい。)

そこで色々と調べた結果、「専用の環境変数をセットすれば Proxy を通せる」コトが判明したので、その方法について備忘録を残します。

事前準備

大前提として、全て macOS でのお話しです。 Windows でも同様の手順を踏めば行けるハズです。)

Charles のインストール

公式サイト からインストーラをダウンロードして、インストールしましょう。

途中、Privileges の許可を求められるので許可してあげましょう。

なお、Charles は有償($50)のソフトウェアで、試用版は起動時などに少し待たされたり、30分経過すると機能が無効化されアプリの再起動が必要になるなどの制約があります。

Rewrite の設定

f:id:monry84:20190605195157p:plain

メニューの Tools > Rewrite から設定します。

f:id:monry84:20190605195423p:plain

  1. 左の Add から設定を追加
  2. Location の追加をします
    f:id:monry84:20190605200113p:plain
    • ポートとかはなくても大丈夫かも?
  3. Rule を追加します
    f:id:monry84:20190605195926p:plain
    • Type: Add Header
    • New 欄の Name: Authorization
    • New 欄の Value: Bearer <auth_token>
      • auth_token は Verdaccio とかで発行されるトークンを使いましょう

Charles のオレオレ証明書

作成・書き出し

  1. メニューの Help > SSL Proxying > Install Charles Root Certificate を選択
    f:id:monry84:20190606101738p:plain
  2. Keychain Access が開くので、 Charles Proxy CA をダブルクリック
    f:id:monry84:20190606101855p:plain
  3. 「常に信頼」を選ぶ
    f:id:monry84:20190606102006p:plain
    • パスワードの入力か Touch ID でのロック解除を求められる
  4. 信頼されていると表示されれば OK
    f:id:monry84:20190606102145p:plain
  5. 証明書を書き出す
    f:id:monry84:20190606102235p:plain
    f:id:monry84:20190606102249p:plain
    • pem 形式 での出力が必須

配置

場所に決まりは無いのですが、後述の upm-config.json と同じ場所に配置しておきます。

sudo mkdir -p /Library/Application\ Support/Unity/config
sudo mv ~/charles.pem /Library/Application\ Support/Unity/config/charles.pem

Unity Hub

基本的には Unity Manual に書いてある通りなのですが、一つ嘘があり、セットすべき環境変数PROXY の文字は小文字でないとダメっぽいです。 それを踏まえた手順は以下の通り。

起動用のシェルを書く

ここでは仮に ~/Developer/bin/Unity Hub に置くコトにします。

mkdir -p ~/Developer/bin
echo '#!/bin/bash
export HTTP_proxy=http://127.0.0.1:8888/
export HTTPS_proxy=http://127.0.0.1:8888/
export NODE_EXTRA_CA_CERTS="/Library/Application Support/Unity/config/charles.pem"
nohup "/Applications/Unity Hub.app/Contents/MacOS/Unity Hub" &>/dev/null &' > "~/Developer/bin/Unity Hub"
chmod +x "~/Developer/bin/Unity Hub"

Unity Package Manager 用の設定を記述

環境変数により証明書のパスを渡しているので、この作業が必要なのかイマイチ分からないのだけど、一応マニュアルに従ってみます。

{
  "caFile": "/Library/Application Support/Unity/config/charles.pem"
}

Unity Hub 起動

~/Developer/bin/Unity\ Hub

PATH 通しておくと便利かも。

これで、起動時にエラーが起きなければ成功です。

Unity Editor

どうやら、Unity Hub から Unity Editor を起動する際に、環境変数を引き継いでくれていないようで、ウンともスンとも動きません。 かと言って、Unity Editor 起動用のシェル書くのも、折角の Unity Hub の機能を使えなくなってしまうので残念な感じです。 なので、ここではグローバルな環境変数を設定して Unity Editor にも環境変数を渡すようにしてみます。

launchctl setenv 用設定ファイル作成

下記のファイル達を ~/Library/LaunchAgents/ 以下に置きます。

setenv.Charles.HTTP_PROXY.plist

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
  <plist version="1.0">
  <dict>
  <key>Label</key>
  <string>setenv.Charles.HTTP_PROXY</string>
  <key>ProgramArguments</key>
  <array>
    <string>/bin/launchctl</string>
    <string>setenv</string>
    <string>HTTP_PROXY</string>
    <string>http://127.0.0.1:8888</string>
  </array>
  <key>RunAtLoad</key>
  <true/>
  <key>ServiceIPC</key>
  <false/>
</dict>
</plist>

setenv.Charles.HTTPS_PROXY.plist

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
  <plist version="1.0">
  <dict>
  <key>Label</key>
  <string>setenv.Charles.HTTPS_PROXY</string>
  <key>ProgramArguments</key>
  <array>
    <string>/bin/launchctl</string>
    <string>setenv</string>
    <string>HTTPS_PROXY</string>
    <string>http://127.0.0.1:8888</string>
  </array>
  <key>RunAtLoad</key>
  <true/>
  <key>ServiceIPC</key>
  <false/>
</dict>
</plist>

setenv.Charles.NODE_EXTRA_CA_CERTS.plist

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
  <plist version="1.0">
  <dict>
  <key>Label</key>
  <string>setenv.Charles.NODE_EXTRA_CA_CERTS</string>
  <key>ProgramArguments</key>
  <array>
    <string>/bin/launchctl</string>
    <string>setenv</string>
    <string>NODE_EXTRA_CA_CERTS</string>
    <string>/Library/Application Support/Unity/config/Charles.pem</string>
  </array>
  <key>RunAtLoad</key>
  <true/>
  <key>ServiceIPC</key>
  <false/>
</dict>
</plist>

launchctl で読み込み

launchctl load ~/Library/LaunchAgents/setenv.Charles.*

起動時に勝手に読み込んでくれるので、マシン再起動(か、再ログイン)でも OK です。

Unity Hub から起動

Unity Hub から Private Registry を参照するプロジェクトを開きます。

Unity Package Manager とかでエラーが起きていなければ成功です。

まとめ

Scoped Registry 自体が 2019.1 で初お披露目された機能なので、バリバリ過渡期な感じですが、環境変数の件とかプロクシの件とかは追々解決されていくんじゃないかと思っています。

なお、 Unity Package Manager が Scoped Registry の認証に対応するのは Unity 2020.1 を予定している っぽいです。

💭(最近マトモに C# 書いてない気がする…。)