【Angular】ローカル環境下のSPA(シングルページアプリケーション)を常時SSL(https)化に対応させる方法


2020/03/29

自社のWebサービスをクラウド化していくと、サードパーティのAPIエンドポイントを踏むときなどに、常時SSL化を要求されることもあります。

angularでSPAをローカル環境下で開発していく段階でも、
http://localhost:4200のまま試験的に外部のAPIを呼び出す際には、常時SSL化対応を促すような警告が出るようなサービスもあります。

本番用のドメインは既に
httpsに対応済みですが、そろそろ開発段階でも常時SSL化したくなってきたので、そのときの手順をメモしておきます。


opensslのインストール

まずはお手元のOS周りにも依りますが、opensslをインストールします。

各OSでのインストール手順は割愛させていただきます。

このブログの内容で動作させているOSは
alpine linuxですが、opensslをインストールしますと、

            
            $ openssl version
OpenSSL 1.1.1d 10 Sep 2019
        
が、今インストールされているバージョンのようです。


認証キーの生成

それではopensslでserver.keyという名前で認証キーを生成します。

カレントディレクトリ配下に、とりあえず
sslというフォルダを作成して、このフォルダの中で作業します。

            
            $ mkdir ssl
$ openssl genrsa -out ssl/server.key 2048
Generating RSA private key, 2048 bit long modulus (2 primes)
..........................................................+++++
.............................................+++++
e is 65537 (0x010001)
$ ls ssl/
server.key
        


証明書署名要求ファイル(CSR)の作成

次に先程の認証キーから、証明書にあたるファイルをserver.csrという名前で作成します。

            
            $ openssl req -new -key ssl/server.key -out ssl/server.csr
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:JP
State or Province Name (full name) [Some-State]:Kumamoto
Locality Name (eg, city) []:Kumamoto
Organization Name (eg, company) [Internet Widgits Pty Ltd]:Tacos Kingdom LLC
Organizational Unit Name (eg, section) []:
Common Name (e.g. server FQDN or YOUR name) []:localhost
Email Address []:contact@tacoskingdom.com

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:*****************
An optional company name []:
        
上のような感じで対話的に聞いてくるので、埋められる箇所は埋めておきます。

何事もなければ、

            
            $ ls ssl/
server.csr server.key
        
となって、CSRが出力されているはずです。


SSL証明書(CRT)の作成

最後に、上の2つのファイルで、SSL証明書であるCRTファイルを作成します。

このファイルは、正規には認可された証明局へ登録・発行されるファイルらしいです。

今回のような用途ではローカルで限定的に使う分には、自分で発行し、自分で認証する、ような使い方になります。

            
            $ openssl x509 -days 365 -req -signkey ssl/server.key -in ssl/server.csr -out ssl/server.crt
Signature ok
subject=C = JP, ST = Kumamoto, O = Tacos Kingdom LLC, CN = localhost
Getting Private key
$ ls ssl/
server.crt server.csr server.key
        


angular.jsonの編集

さて、なにか任意のangularプロジェクトがあり、先程作成したsslファイルをangular.jsonと同レベルのディレクトリに配置します。

treeすると以下のようなフォルダ構造です。

            
            $ tree
.
├── angular.json
#...他の中身は中略
└── ssl
    ├── server.crt
    ├── server.csr
    └── server.key
        
ここから、angular.jsonの中身を編集します。

編集する箇所は以下のような
serveの箇所です。

            
            //...中略
    "serve": {
        "builder": "@angular-devkit/build-angular:dev-server",
        "options": {
            "browserTarget": "ng-playgound:build",
            "sslKey": "./ssl/server.key",
            "sslCert": "./ssl/server.crt"
        },
        "configurations": {
            "production": {
                "browserTarget": "ng-playgound:build:production"
            }
        }
    },
//...以下略
        
これでlocalhost:4200のhttps化が完了です。


serveしてみる

では早速、SPAを起動してみます。

起動には
--sslオプションを付けると、sslが有効になります。

            
            $ ng serve --ssl
        
まずは、chromeでどんな感じなのかをみますと、

合同会社タコスキングダム|蛸壺の技術ブログ

...いの一番になんだかデカデカと警告がきます。

なんだか期待していたのと違いますが、とにかくそれでも
localhostにアクセスすると、

合同会社タコスキングダム|蛸壺の技術ブログ

となり、それ以降はデカデカとした警告画面なしで、
https://localhost:4200にアクセスできるようになるようです。(まぁ、アドレスバーには保護されていない通信の警告は相変わらず残りますが...)

そもそも、さっき作った自分発行のSSL証明は効いているんだろうか?とおもって設定を確認すると、以下のように
証明書(無効)となっているようです。

合同会社タコスキングダム|蛸壺の技術ブログ

作成した自分専用の証明書はきっちりと読み込まれているようでした。

その後も
ChromeではSSL有効にするのにSAN(subjectAltName)を設定する必要があるとのことで、SANの設定も繰り返し上手くいけてそうな設定を行ってはみたものの、証明書が有効にならないのはなんででしょう…

合同会社タコスキングダム|蛸壺の技術ブログ

所詮は自分証明書ですので、ブラウザにフィッシーな認証局として扱われているのでしょうか...

これ以上opensslではバージョンごとやブラウザごとに挙動が違いすぎるので、細かい設定を弄ってみても埒が明かない...ので別アプローチを次回以降やってみたいとおもいます。


そうだ、mkcertにしてみよう

opensslで吐き出した証明書での常時SSL化はFirefoxではどうやってもダメだそうですので、opensslでのssl化はここらへんで断念しました...

別方向で
mkcertという今回の目的にうってつけのツールがあるようです。

openssl設定を用いたSPAのローカルのhttps対応は個人的にハードルが高く断念し、
mkcertというローカル環境で自分認証の発行とインストールまでやってくれる便利ツールを使って、早速以下の内容で、リベンジを図りましょう。


mkcertのインストール

公式の手順通りに、手元のMacbookでbrewからイントールするのが最も早そうなので以下のコマンドでインストールします。

            
            $ brew install mkcert
$ brew install nss
        
なおWindowsやlinuxなど他のOSでmkcertを使う場合には公式の手順をご参照ください。

brewでインストールしたら、早速自分認証を発行してみます。

            
            $ mkcert -install
Created a new local CA at "/Users/********/Library/Application Support/mkcert" 💥
Sudo password:**************
The local CA is now installed in the system trust store! ⚡️
The local CA is now installed in the Firefox trust store (requires browser restart)! 🦊
        
これでmkcertの準備が完了し、実際にSPAで起動したいドメイン名(複数名指定可能)を指定して以下のようにコマンドを叩くと、

            
            % mkcert localhost 127.0.0.1
Using the local CA at "/Users/*******/Library/Application Support/mkcert" ✨

Created a new certificate valid for the following names 📜
 - "localhost"
 - "127.0.0.1"

The certificate is at "./localhost+1.pem" and the key at "./localhost+1-key.pem" ✅
        
現在の作業ディレクトリにlocalhost+1-key.pemlocalhost+1.pemの二つの自分認証ファイルが発行されました。

この2つのファイルは、上記の
opensslの項目で利用していたserver.keyserver.crtに、それぞれ置き換えてみます。

            
            $ cp localhost+1-key.pem {angularのプロジェクトまでのパス}/server.key
$ cp localhost+1.pem {angularのプロジェクトまでのパス}/server.crt
        
前回の繰り返しになりますが、プロジェクトのフォルダ構造は以下のようになっていると思います。

            
            $ tree
.
├── angular.json
#...他の中身は中略
└── ssl
    ├── server.crt
    └── server.key
        


動作の確認

ここまで出来たら早速前回と同様SPAを起動してみます。

            
            $ ng serve --ssl
        

Chromeでの挙動

まずはchromeからSPAの動作を確認してみます。

合同会社タコスキングダム|蛸壺の技術ブログ

なんとあれだけの設定で、自分認証が有効になっています。

合同会社タコスキングダム|蛸壺の技術ブログ

以下がmkcertで発行された証明書ですが、ローカルOSが発行元になっているようです。

合同会社タコスキングダム|蛸壺の技術ブログ

Firefoxでの挙動

最後にfirefox上で確認です。

合同会社タコスキングダム|蛸壺の技術ブログ

これもきちんとhttpsとして動作しております。

恐るべしmkcert、といったところです。

合同会社タコスキングダム|蛸壺の技術ブログ

合同会社タコスキングダム|蛸壺の技術ブログ

個人的には、諦めていたfirefoxでhttps化したSPAが動作するなんて感激です。


まとめ

玄人志向なツールであるopensslに比べて、mkcertを使うことでローカル環境でもお手軽にangularのSPAを常時SSL対応できることがわかりました。

これでよりセキュアなangularのSPA開発が捗りそうです。


参考サイト

Create a Valid SSL in Localhost for Angular Applications

nginxでオレオレ証明書をする

数分でできる!mkcertでローカル環境へのSSL証明書設定

ローカル環境でSSLをオレオレ証明書で行っていて警告が出てる人に朗報

Nginx版:mkcertを使ってローカル環境でもDockerでも楽々SSL


Angularの学び方

主要なJavascriptのフレームワークの一角であるAngularは、現在Google主導で開発が進められている玄人フロントエンジニア向けのフレームワークです。

Angularを使えばかなり高度なWebアプリも自由に作成できるのですが、やはり初心者が独学で勉強しようとおもうとかなりの知識が必要でAngularは挫折しやすいと言われています。

特にAngularを使う上で注意が必要なのは半年に一回のペースでプログラムのメジャーバージョンが繰り上がるので、他のフレームワークと比べても格段に技術を追っかけるスピードが早いことも躓く人が多い一因になっているとも思います。

Udemyの動画講座では、基礎からじっくり学べるためより実践的なスキルを身につけることが可能です。以下の講座ではAngular初心者向けに簡単なプロジェクトの作成まで学ぶことができます。

より実践的にフロントエンジニアとして重宝されるためにはSPA(シングルページアプリケーション)をある程度作成できるスキルが必要になりますので、さらに学びたい方は以下のような講座も用意されています。

他にもAngularプログラミングの習得度に応じた講座も多数用意されているので、必要に応じて試されてはいかがでしょうか。