例えばローカルアプリ (unity) で OAuth2 認証を行う場合、一旦ブラウザで認証を行った後アプリに戻りたい。ニッチですが、そんなケースがあるでしょう。
日々セキュリティリスクに晒されているからこそセキュリティ対策万全な Web サイトで認証のみ行い、それが成功したらアプリに実行を移す…なんて事もあるかもしれません。
例えば Google Drive や Spread Sheet アクセスするための Google 認証 では処理終了後に、任意のループバック HTML が実行されます。
<html>認証に成功しました。アプリ 'XXX' を続行してください。</html>
このループバック HTML なら認証後「認証に成功しました。アプリ 'XXX' を続行してください。」と表示されますが、どうせなら自動的にアプリに戻って欲しいですよね。
ここでは URI スキーマという方法を用いて、ブラウザから特定のアプリに戻る方法を実践します。
URI スキーマとは
VSCode をインストールしている人なら試してもらいたいのですが、ブラウザの URL 欄に「vscode:」と入力してエンターを押すと、こんな表示になります。
http, https の代わりに「定義された名称で、特定のアプリを開く」のが URI スキーマです。
他にも「msnweather:」と入力すると天気を表示したり、「microsoft-edge:」では現在のブラウザがなんであろうと Edge を起動したりします。
この「定義された名称」はレジストリ コンピューター\HKEY_CLASSES_ROOT
に登録されています。
VSCode もありました。
レジストリを追加する
これと同じものを自分で登録してみよう。というわけで以下を testcalc.reg という名前で保存し、実行してください。
「testcalc」が定義された名称で、最終行の実行ファイルが特定のアプリとなります。
testcalc は全部で5か所あります。間違えのないよう、全て同じ名前にしてください。
Windows Registry Editor Version 5.00 [HKEY_CLASSES_ROOT\testcalc] @="url:testcalc protocol" "URL Protocol"="" [HKEY_CLASSES_ROOT\testcalc\shell] [HKEY_CLASSES_ROOT\testcalc\shell\open] [HKEY_CLASSES_ROOT\testcalc\shell\open\command] @="C:\\Windows\\System32\\calc.exe"
実行するとこのようなダイアログが表示されます。
(Windows のバージョンや、セキュリティ強度によっては異なる表示かも)
この警告は「既に testcalc というレジストリがあった場合、上書きされて元からそれを使っていたツールやアプリが動かなくなるかもしれないよ」という警告です。
testcalc という名前をレジストリ登録している市販のツールはほとんどないと思いますが…、心配な場合はレジストリエディターで コンピューター\HKEY_CLASSES_ROOT\
に testcalc という名前のレジストリキーがないか確認しておきましょう。
レジストリーの直接調査は今も昔も、危険な操作であることに変わりありません。
ブラウザで testcalc: と入力する
問題なくレジストリが作成されたら、ブラウザで「testcalc:」(最後はコロン)と入力し、エンター。
こんな風に、計算機を開くか聞かれれば成功です。
C:\Windows\System32\calc.exe にお目当てのファイルがない場合はこのように表示されます。
上手くいかなかった場合は、calc.exe を自分の環境で探し、そのファイルパスを入力してください。
別に calc.exe じゃなくても、確認するだけなのでなんでも OK。
コンピューター\HKEY_CLASSES_ROOT\testcalc を消しておく
テストは成功したので、(レジストリエディターで)一旦消してしまいましょう。
消した後、再びブラウザで testcalc: と入れても計算機は起動しなくなります。
unity のコードでレジストリを登録する
以下の unity コードで開始時にレジストリを作成できますが、いくつか注意点があります。
- レジストリは Windows のみに通用するルールなので、他のプラットフォームではビルドしない
- 実行には管理者権限が必要(Unity Editor では実行できずエラーになる)
ループバック HTML で URI スキーマが実行されるようにする
リダイレクト機能で「作成した URI に飛ばす」ようにしてあれば、ブラウザから計算機に戻ることができます。
<head><script>location.href = 'testcalc:';</script></head><html>Success authorization. Go back to app.</html>
using UnityEngine; #if UNITY_STANDALONE_WIN using Microsoft.Win32; #endif public class Main { [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)] static void main() { #if UNITY_STANDALONE_WIN const string URI_SCHEMA = "testcalc"; const string EXECUTE_PROCESS = @"C:\Windows\System32\calc.exe"; var testcalc = Registry.ClassesRoot.CreateSubKey(URI_SCHEMA); testcalc.SetValue(null, @"url:testuri protocol"); testcalc.SetValue("URL Protocol", ""); var shell = testcalc.CreateSubKey(@"shell"); var open = shell.CreateSubKey(@"open"); var command = open.CreateSubKey(@"command"); command.SetValue(null, EXECUTE_PROCESS); #endif } }
1つ目は当たり前として、2つ目が厄介ですね。レジストリ操作はセキュリティリスクの高い内容なので致し方ないのですが…。
ビルドした exe を 右クリック > 管理者として実行
すればレジストリは作成されますが、通常の権限だと作成されません。
Unity Editor で実行した場合はエラーが表示されます。
終わりに
実際にアプリを作る際、unity だけではなくこういったマメ知識も必要になりますよね。
「興味を少しでも持った時」に軽く調べる癖をつけておくと、後々「あ、俺それ出来ますよ」なんてカッコイイ! ステキ! …かどうかは置いといて、スマートな仕事に繋がるのではないでしょうか。
iOS や Android については、必要になったら記事にしようと思います。