著者アーカイブ takahashi

takahashi 著者:takahashi

Nexus7(2012)を充電時に自動でOSを起動するようにしてみた

最近、使ってなくてほこりをかぶっていたタブレット…Nexus7の2012年モデルを、車のナビ専用端末に仕立てようといろいろセットアップしていたのですが、車のナビにする以上、エンジンと連動して起動したり、停止したりしてほしいのですが、元々汎用用途であるAndroidタブレットだとなかなかその挙動が難しかったりします。

SmartConnectというアプリを使うと何かの”きっかけ”(例えばイヤホンケーブルにつないだ時、とか、充電機器に接続したとき、とか)をもとにして自動でアクションをさせられるので、OS起動後にBluetooth機器に接続されたときなどにナビアプリの自動起動と音楽の再生、接続が切れた時(=エンジンを切ったとき)にホームへの移行や、音楽の停止などを行わせる所まではできたのですが、唯一タブレットの電源onについてはOSが起動する前の挙動なので、アプリではなかなか変更が難しいところです。

ただ、出かける前にタブレットを台に乗せてケーブルをつないで、さらに電源もONにするとなると、埋め込み型のナビと比較してかなりめんどくさいので、何か一つだけでも自動化できないかといろいろ調べていたところ、こちらの記事を発見。

nexus7で充電開始時に自動で電源オンにする設定(root不要)- hycko.blog

root化不要でこんな設定ができただと…
なんでもブートローダーの設定をPC(ADB)経由で変更してやることで、充電専用ケーブル・通信用ケーブル関係なく充電器と接続した時点でAndroidが自動起動してくれるようになるとのこと。

…でも、ブートローダーなんてroot化やROM焼きなんかに出てくるあれだよね…そんな簡単に触れるもんなのか…と疑心暗鬼になりながらも、とりあえず試してみましたところ….

想像以上に簡単でした\(^q^)/

(※写真はNexus7 2013ですが、実際はNexus7 2012で検証しました。なお、Nexus7 2013もブートローダーの起動までは同じ手順でできました。)

簡単に手順をまとめると、下記のようになります。(※メーカーの修理を受けれなくなる可能性のある内容です。試される場合は自己責任の下行ってください。)

1.Androidの設定->開発者ツールから、USBデバッグを有効にします。
(※開発者ツールはデフォルトでは非表示になっています。こちらの方法で開発者ツールを表示させてください。)
2.PCにUSBで接続し、次のコマンドを実行します。(Android Studioをあらかじめインストールしている必要があります。)

adb reboot bootloader

Nexus7が再起動して、ドロイドくんのおなかの蓋があいている絵のある画面が出てきます。

これが”ブートローダー画面”のようです。
この画面が出てきたら、次のコマンドを入力します。

fastboot oem off-mode-charge 0

すると自動でNexus7が再起動され、いつも通りAndroidが立ち上がります。
Androidの起動が完了したら、一旦USBケーブルを抜いた状態で電源を切り、充電専用のUSBケーブルで充電器とNexus7をつないでみます。

すると、電源ボタンを押さなくても電源が自動で入るようになりました!
なお、再び充電専用ケーブルと充電器をつないでも起動しないようにするには

fastboot oem off-mode-charge 1

とすればよいようです。

自分はもう使わなくなったタブレットを再利用してるので設定変更を行いましたが、簡単にできるとはいえ通常はブートローダーの設定を変更すること自体かなりリスキーな作業になります。
お手元のNexus7(2012)で試される際は自己責任のもと、慎重に行っていただきますようお願いします。
(ブートローダーの起動自体は他のAndroid端末でも行えるかもしれませんが、設定の変更については正常にできる保証はない(機種によってはメーカーがブロックしている可能性がある)ので、確証がない限り試さないことをお勧めします。)

takahashi 著者:takahashi

GoogleChrome 70 がリリース HTTPページの警告の厳格化やPWAの正式対応などが追加

いつの間にかGoogleChrome Ver.70がリリースされていたようですね。

New in Chrome 70 – Google Developers

米国現地時間の10月16日にリリースされたVer.70では、幾つか大きな変更がされているようです。

・非SSLサイトで文字入力を行うと、アドレスバーに赤文字の”保護されていない通信”が表示されるように変更

ついに、SSL通信(アドレスがhttps://から始まるもの)に対応していないサイトで、フォームなどのテキストボックスに文字を入力すると、無効なSSLが設定されたサイトと同様にアドレスバーの”保護されていない通信”の表示が赤文字に変化するように変更されました。

これは以前から予告されていた変更で、Chromeの”常時SSLが基本”という考え方を反映した物にするために、段階的に変更されてきたものです。

Moving towards a more secure web – Google Security Blog

入力フォームのない非SSLサイトでは、黒文字の”保護されていない通信”が表示されるだけですが、入力フォームの存在する非SSLサイトの場合は入力フォームに一文字でも何か文字を入力した時点で、アドレスバーの”保護されていない通信”が無効なSSL証明書を搭載したサイトと同様に赤文字に変わります。

事情を知っているユーザーならまだしも、こういった事情を知らない一般ユーザーからすると、セキュリティ的に問題のあるサイトとして見られてしまう可能性があります。

そもそもChromeがこういった対応をする前から、ユーザーになにか情報を入力させる機能を提供する場合はSSLに対応するのが常識でしたし、最近はLet’s Encryptのような無料のSSL証明書もでていますので、まだSSLに対応されていないサイトをお持ちの方はすぐにSSL対応化していただくことをお勧めします。

・Windows版ChromeがPWAに正式に対応

いままで実験的機能として実装されていたPWA(プログレッシブウェブアプリ)ですが、ついにWindows版Chromeで正式に有効化されたようです。
PWAとはWebアプリとして提供されているインターネット上のWebサイトを、あたかもネイティブ(OSにインストールしたような)アプリとして動いているかのように動作させるできることができる機能です。

通常、Webサイトとして作られたWebアプリは、インターネットにつないでいないと起動できないうえ、ユーザーがWebサイトを開かないと何もできない受動的な仕組みでした。
PWAが有効になることで、こういったWebサイトをPWAに対応させることで、対応ブラウザを通してOSのアプリの一つとしてインストールできたり、インターネットに接続していなくても起動できたり、Webサイトを閉じていても通知が受け取れたり、といった恩恵が受けられるようになります。
またPWAの本質はWebサイトなので、各OS用にプログラムを書き直したり、ビルドし直したり、といった作業をほとんどすることなくクロスプラットフォームアプリを作れるのも大きな利点です。

有名どころでは、現時点でTwitter LiteGoogle PhotoなどのサービスがPWAに対応していますので、早速体験してみたい!という方は是非試してみてはいかがでしょうか。

Twitterにアクセスできなくなった「Twitter for Mac」の代わりはChromeのPWAで「Twitter Lite」を使うのが最適? – AAPL.Ch

なお、公式ブログによると、macOS版ChromeではVer.72で正式対応予定とのことですが、早く試したいという方は従来通り実験機能を有効にすることで現時点でも利用できるようになります。(有効化の方法は上記記事をご覧ください。)

・WebWorkerで実装した各処理に名前を付けることが可能に。

WebWorkerとは、javascriptの処理をバックグラウンドで行わせることができる仕組みです。

Javascriptは少し特殊で、基本的にすべての処理をメインスレッド(メインのプロセス)だけで行います。
そのため、Javascriptで書いたプログラムのどこかで重い処理を行ってしまうと、その処理が終わるまでほかの処理を行うことができないため、結果的にWebアプリがフリーズしたような状態になってしまうことがありました。

こういった処理にWebWorkerを使用することで、その部分の処理はメインスレッドとは別のスレッド(プロセス)で行わせることができるため、重い処理を行わせてもWebアプリがフリーズしにくくなり、快適な動作をさせることができます。

今回のアップデートで、WebWorkerで書かれた各処理ごとに名前が付けられるようになったようで、これにより複数のWebWorkerを使用した場合のデバッグがしやすくなるようです。

ほかにも多くの修正が行われたChrome Ver.70。
今回は魅力的な機能もいくつか正式実装されているようですので、Chrome使いの皆さんは変更点を是非チェックしてみてください。

takahashi 著者:takahashi

[要注意]3TB ストレージを搭載したiMac (27-inch, Late 2012)モデルではmac OS MojaveでBootcampを使用できない。

自分はMacBookAirを使用しているのですが、先日リリースされたmacOS MojaveでもBootcampを利用できるのか一応確認しておこうと思っていろいろ調べていたところ、ある事実が判明しました。

「Boot Camp が設定されているため、インストールを続けられません」という警告が表示される場合 – Apple

3 TB のハードウェアを搭載した iMac (27-inch, Late 2012) をお使いの場合は、「Boot Camp」パーティションを削除してからでないと、macOS Mojave 10.14 をインストールできません。macOS Mojave にアップグレードした後、その Mac に Boot Camp を使って Windows をインストールすることはできなくなります。

という表記が…

さらに下の方にはしっかりと枠で囲んだうえで

このような iMac に macOS Mojave をインストールした場合、Boot Camp を使って Windows をインストールすることはできません。

とはっきりと書かれています。

説明書きにもある通り、Mojaveにアップグレード後すべての機種でできなくなるというわけではなく、”3 TB のハードウェアを搭載した iMac (27-inch, Late 2012) “が対象になるとのこと。

さらに調べていくと、Appleのコミュニティに下記のような記述がありました。

MojaveでBootcamp(Windows10)のインストールは可能? – Appleコミュニティ

内蔵hddが3TBあると、2.2GB直前の領域に連続した領域をWindows用に用意しようとするようです(こうしないとbootcampではWindowsを起動できないため)。このため、macOSの領域はhddの前半と、後半に分割されます。ユーザには、これらを連続した領域として使えるように見せます。このため、かなり複雑な動作をします。fusion driveはやっとmojaveからapfs対応になりました。まだバグもあるのかもしれません。

という記述があり、どうやら3TB以上のストレージを積んだPCでは、Mojave上でBootcampを動かすのが難しいようです。
ただ、今後のアップデートによっては改善される可能性もあるかとは思いますので、該当機種をお使いの方でbootcampを使用する予定のある方はしばらくの間、Mojaveへアップグレードするのは待った方がよさそうです。

takahashi 著者:takahashi

WindowsにVirtIOドライバをインストールする方法

サーバー準仮想化の仕組みの一つに、”VirtIO”というものがあります。
例えば仮想マシンでNIC(ネットワークアダプタ)やディスクドライブをソフトウェアで完全に仮想化してしまうと、物理ハードで動かした場合と比較して必要な処理が多くなり、オーバーヘッド、つまり余分な負荷が増えてしまいます。
余分な負荷が増えることで、結果として可能マシンの動作が遅くなってしまうのです。

仮想マシンの仕組み上からこのオーバーヘッドを少しでも減らす方法の一つとして、一部の処理を物理的なハードウェアに直接行わせてしまう”準仮想化”という方法が用いられます。完全な仮想化ではないので”準”仮想化です。

VirtIOも、ディスクへのアクセスやネットワークへのアクセスを”準仮想化”する仕組みの一つで、最近の主要な仮想マシンやクラウドサービスなどでよく使われています。
VirtIOを使用することで、完全仮想化されたハードウェアを使用する場合と比較してより高速に仮想マシンを動作させることができます。

Linuxディストリビューションには標準でVirtIOドライバが含まれている場合が多いのですが、Windowsの場合、初期状態ではVirtIOドライバがインストールされていないのでドライバのインストールが必要になります。

今回は、セットアップ済みのWindowsにVirtIO-NETドライバをインストールする方法をご紹介します。

VirtIOのドライバはfedoraプロジェクトのサイトで配布されています。

Creating Windows virtual machines using virtIO drivers – fedoraDOCS

この中の
Stable virtio-win iso
を選択し、isoファイルをダウンロードします。

isoファイルを入手したら、各仮想マシンに光学ドライブとしてマウントします。
マウントする方法は仮想マシンソフトによって操作方法が異なるため、各ソフトのマニュアルを参照してください。

OSからは光学ディスクドライブ(CD/DVDなど)として認識されていればOKです。
マウントが完了したら、デバイスマネージャーを開いてください。

デバイスマネージャーはコントロールパネル(コントロール パネル\システムとセキュリティ\システム)、またはWindowsロゴ(スタートメニュー)を右クリック->デバイスマネージャーから開くことができます。

デバイスマネージャーを開くと、いくつかの黄色い”!”が表示されているかと思います。

“!”マークが表示されているデバイスを右クリックし、”ドライバーソフトウェアの更新”をクリックします。


するとこちらのダイアログが表示されるので
“コンピュータを参照してドライバーソフトウェアを検索します”
をクリック。

下記画面が出てくるので…


先程VirtIOのISOイメージをマウントしたドライブを選択します。
すぐ下の”サブフォルダーも検索する”もかならずチェックを入れてください。


適合するドライバの検索が始まります。

途中、許可を求められた場合は”インストール”をクリックしてください。

下記の画面になればインストールは成功です。

デバイスマネージャーで”Red Hat VirtIO Ethernet Adapter”が追加されていれば、正常に動作しています。

なお、ディスク側のVirtIOのインストールは、先にOSがインストールされたディスクをVirtIOに切り替えてしまうと正常に起動しなくなる可能性があります。
ストレージを完全仮想化状態のままにしてOSを起動し、外付けのVirtIOディスクを追加したうえでドライバーをインストール、作業が終わったらシステムディスクをVirtIOに変更すればOKのようです。

詳細はこちらの方の記事を参照してください。

KVM上のWindowsでVirtIOを利用する – 出力を入力へ

VirtIOはセットアップはめんどくさいですが、動作速度の改善が測れますし、やっておいて損はないかと思います。
仮想マシンを利用されている方は是非試してみてはいかがでしょうか。

takahashi 著者:takahashi

Appleが突如10/30に発表会をスケジュール!何が発表されるのか気になる…

突如としてAppleがイベントの開催を告知しました。

Apple Special Event – Apple
速報:Apple、前代未聞の招待状で10/30イベント開催を告知 NYで何が発表されるか徹底予想 – engadget日本版

今度こそベゼルレスのiPad Proや新型macbookAirが発表されるのでは、という予想もたてられているようですね。

この前のGoogleのイベントで、Pixel3を”iPhone Xsよりも優れた製品”として大々的にアピールしたので、
こちとら黙ってはいられない…!
というところもあるかもしれませんね。

こちらの発表会イベントは日本時間で10/30(火)23:00から行われるとのことなので、この前のGoogleのイベントよりは見やすい時間帯となっています。

新製品発表の瞬間をリアルタイムで見られるチャンスですので、是非チェックしてみてはいかがでしょうか。

takahashi 著者:takahashi

ついにメールサーバーがハード製品として販売される時代に!? メールサーバー専用ガジェット「Helm」

なんとメールサーバーそのものを個人宅向けの専用デバイスにして販売を開始した企業が現れました。

Helmという製品です。

Helm

誰でも簡単に自分のメールを自分で管理しセキュアに運営できるメールサーバーが作れる「Helm」- Gigazine

ドメインの取得とインターネット回線は必要ですが、その他機器は一切不要で、Helm側のクラウドゲートウェイを利用するので固定IPの割り当ても不要となっています。

Helmのコンセプトは”データのユーザー完全所有化”で、この辺りの思想はownCloudNextCloudに近いものを感じます。

一般的によく使われるフリーのメールサービスは、各サービスの管理をする企業が管理するサーバーにデータが保存されるため、企業によっては自分のメールデータを勝手に閲覧されてしまう可能性もありますし、たとえプライバシーに慎重な企業が管理していてのぞき見の心配はなかったとしても、クラッキングによるデータ流出のリスクから逃れることはできません。

一方Helmは、メールデータはすべてエンドツーエンドで暗号化され、Helm側が一切データの中身を見ることができない仕様になっているとのこと。


※写真は公式サイトをGoogle翻訳で日本語にしたものです。

さらに、端末内の暗号化を解除する唯一の秘密鍵も専用の物理ストレージになっていたり、Helm自体の起動にもセキュアブートが採用されていたりと、データ流出対策にとても気を配った設計になっていることがうかがえます。

ネット上のサービスを利用する場合と違い、いままで自宅サーバー、いわゆるオンプレミスのサーバーを手に入れるためには自力で環境を構築する必要がありました。
もっともそれが醍醐味だったりしたわけですが、最近は同じようなことがハードをそろえなくてもネット上でできるようになったため、こういったサービスを利用する人が増えていきました。

一方でオンプレミスの方は今回のHelmのような、”知識や高価な機器がなくても構築できる”系の機器が増えているような印象がありますし、今後は一般ユーザー向け製品としての路線へ進んでいくのかもしれませんね。

takahashi 著者:takahashi

[nginx小ネタ]failed (24: Too many open files)が出た時にまず確認したいこと

今回は、先日のちょっとしたやらかし談をご紹介します。

先日新しくサーバーを構築していて、nginxでバックエンドのApacheへのリバースプロキシを構築していたのですが、途中でこんなエラーに遭遇し、サイトが表示されなくなってしまいました。
logを確認するとこんなメッセージが。

accept4() failed (24: Too many open files)

いろいろ調べたところ、OSファイルディスクリプタ数上限の設定やnginxの制限の設定などを変えると解決するという情報を発見て、sysctl.confやらnginxのコンフィグやらを色々変えたのですが、何度試しても同じエラーが出続けて動作せず。

おかしいなーと思いながらもう一度設定ファイルを見返したところ、あることに気づきました。

バックエンドのApacheでは3003番ポートでListenしていて、nginxの3001番ポート経由でバックエンドのサーバーにつなげさせたかったのですが、設定ファイルには

server {
    listen       3001;
    server_name  node.example.com;

   client_max_body_size 1g;
    proxy_set_header Host $host;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Host $host;
    proxy_set_header X-Forwarded-Server $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header  X-Forwarded-Proto \$scheme;


    location / {
        proxy_pass http://localhost:3001; #←!?
    }

}

となっていました。
そう、つまりlocalhostの3003番ポートで動作しているApacheへリバースプロキシさせるはずが、あろうことかnginxが待ち受ける3001番ポート自身をまたリバースプロキシするような設定になってしまっていました。
当然、nginxの待ち受けポートをnginx自身がリバースプロキシしてしまっているので接続が無限にループしてしまい、それが原因でOSの上限を超えてしまっていたというのが今回の原因でした。

すぐに

proxy_pass http://localhost:3003;

に修正したところ、正常にページが表示されるようになりました。

見慣れないエラーが出ると慌ててついいろいろ試してしまいますが、まずは自分の凡ミスを疑ってみることも大事なんだなと思いました(;´∀`)

takahashi 著者:takahashi

普通のメールサーバーでもキャリアメールのようなプッシュ通知を可能にするIMAP IDLEとは

携帯電話やスマートフォンでキャリアメールを使用していると、何もしなくてもリアルタイムでメールを受信することができます。
一方、通常のメールサーバーからメールを受信する際、元々リアルタイム受信は一般的ではなく、ユーザーがメールサーバーに定期的に確認しに行くしかありませんでした。
ところがIMAPというメール受信のプロトコルができてから、こういった従来のメールシステムでも定期的にサーバーに確認することなくメールをリアルタイムで受信することが可能になりました。

具体的には、メールソフトがIMAPサーバーへ接続した際、特定のコマンドをクライアントが発行することで受信操作完了後もIMAPサーバーとの接続を維持し続け、新着メールがあるたびにメールサーバーからクライアントにリアルタイムで通知する仕組みになっています。

この仕組み、およびコマンドををIMAP IDLEといいます。
IMAP IDLEコマンドを使用するには、使用しているメールサーバーがIMAPに対応しており、かつIMAP IDLEコマンドにも対応している必要があります。

自分でフルコントロールできるメールサーバーがあれば、受信サーバーにdovecotなどのIMAP IDLE対応IMAPサーバーを使用することで、自分のメールサーバーに到着したメールをリアルタイムにプッシュ通知させることができます。

DovecotでIMAP IDLE を使った Pushメールを体験してみる – レンタルサーバー・自宅サーバー設定・構築のヒント

しかし、使用しているメールサーバーの管理権限を持っていない場合(通常はこの場合が多いと思います。)、IMAP IDLEに対応していないとこのプッシュ通知を利用することができません。

有名どころでは、現時点で下記のメールサービスはIMAP IDLEに対応しているようです。

・Gmail
・Yahoo!メール

そのほかのメールサービスでもIMAP IDLEが利用できるものがあるようです。各メールサービスのFAQやドキュメントを確認したり、サポートに問い合わせたり等して確認してみてください。

また、IMAP IDLEが利用できないサーバーを利用されていて、それでもIMAP IDLEをつかってプッシュ受信を実現したいということであれば、一旦他のメールサービスを受信させて、そこからIMAP IDLEを使ってプッシュさせる方法があります。

例えば、自分の場合は会社のメールサーバーはPOP3にしか対応していないため、直接IMAP接続することができません。
そこで、フリーのメールサービスであるGmailを使い、一度会社のメールサーバーのメールをPOPでGmailへ受信させ、GmailがPOPで受信した時点でIMAP IDLE経由で各端末へ通知させるような使い方をしています。

Gmailサーバーと会社のメールサーバーはPOPでやり取りしているため、実際には完全なリアルタイムではありませんが、Gmailは比較的リアルタイムに近い時間間隔でPOP受信をかけてくれるため、ほぼ数分程度の誤差でメールを受信することができます。

GmailでPOP受信設定する方法 – heteml BLOG

ただし、Gmailの場合は受信容量に上限(Google Dirveなどのサービスと共用で、1無料アカウントにつき15GB)があるので、無限にメールをため続けることができない点には注意してください。

takahashi 著者:takahashi

ついにPixel 3/Pixel 3 XL の日本発売が正式に発表!

ついに…

ついに!!!

Pixel 3/3 XL 正式発表キタ――――――――――――――――――――――(゚∀゚)――――――――――――――――――――――!!

Google Pixel 3 公式ティザーサイト

いやぁ来ましたね。

Pixel 3はAndroid開発元のGoogle自身が開発したAndroid端末の最新機種です。
見た目はGoogleのロゴが入っていること以外普通のスマートフォンなのですが、実は他のAndroidスマートフォンにはない特徴があります。

1.”Android OS開発元”のGoogleが直接ビルドした”純正のAndroid”が使える。

以前販売されていた”Nexus”シリーズ同様に開発元のGoogleが混ざりけなしのAndroidをインストールしているため、メーカーやキャリア製端末によくある”消せないアプリ”が最小限になっています。
また、メーカーによるAndroidの改造プロセスがない分Android最新版が出た時点でGoogleから直接アップデートを受け取れるため、ほかのAndroidスマホよりも早く新しいOSのバージョンが試せるのも魅力です。

2.Googleの最新機能がいち早く使える

Googleが作ったソフトウェアがそのまま入っているので、Googleが提供する新機能もいち早く試せます。
過去に、先代のPixel2に優先的に搭載された機能として、Googleアシスタント、GoogleLensなどがあります。
また、今回のPixel 3発売とともに、Googleアシスタントがユーザーの代わりに電話に応答し、迷惑電話を撃退してくれる機能も発表されました。

今後新たな機能の発表があった際も、(HWが対応していれば)Pixel 3にも優先的に提供されるとみられます。

3.カメラ性能
背面カメラは12.2 メガピクセルとSonyのXPeriaシリーズよりは劣りますが、光学ズームを搭載しており、Googleの得意分野であるAIを使用した強力な画像補正技術により、非常に綺麗な写真を撮ることができるとのこと。

また、暗いところでも綺麗に撮れるNight Sight機能、
シャッターチャンスを逃してしまっても、シャッターの前後の写真から一番良いものを後から選べる機能など、アマ以上のカメラマンも垂涎の機能がたくさん盛り込まれています。

今回の発表が特に盛り上がった理由として、こういった機能面だけではなく、日本発売が絶望視されてきたPixelシリーズの端末の日本国内発売がされた点があります。
以前の記事でも説明しましたが、日本ではNexusシリーズを最後に、Google純正の端末がしばらく発売されてきませんでした。

その分、久々の純正端末の発売決定は反響が特に大きかったようです。

最近発売されたiPhone XS/XR と単純に比較すると微妙なところではありますが、Google・Androidファンにとってはかなり魅力的な一台なのではないかなと思います。

takahashi 著者:takahashi

nginxやAmazon ALBなどのロードバランサー経由でLaravelにアクセスさせたときにHTTP/HTTPSを振り分ける方法

nginxやロードバランサーなどを使ってWebサーバーにアクセスさせた際に困るのが、一部の情報が本体のWebサーバーまで到達しない点。
特に、クライアントがHTTPでアクセスしているのか、HTTPSでアクセスしているのか、などの情報はそのままの状態で取得するのは困難です。

こういった環境と、HTTPかHTTPSどちらで接続されているのかを判定したうえでDOMのURLを書き換えるタイプの機能を持つフレームワークやプログラムとの相性は特に最悪で、Webサーバーに対してHTTPでアクセスされた時点で”クライアントからHTTPでアクセスされている”と判定して、すべてのアセットのアドレスをhttp://から始まるURLに置き換えて返してしまい、結果jsやcssが読み込めずに表示崩れや不具合になってしまうことがあります。

最近人気のLaravelもこの機構を持っており、そのままの状態でnginxやLBを間に置いてしまうと、httpsでアクセスしたときにページが正常に表示されない問題が発生してしまいます。

幸いにも、HTTPSかどうかの部分についてnginxやロードバランサーが代わりに取得し、その情報をヘッダーに含めて投げてくれる場合が多いので、今回はLaravel上でこのヘッダ情報を使って簡単にHTTP/HTTPSを判定できるようにしてみました。

Laravelプロジェクトフォルダ内の
routes/web.php
の最初あたりに、次のコードを追加します。

<?php

// 2018/10/26追記: 一部修正しました。

/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
|
| Here is where you can register web routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| contains the "web" middleware group. Now create something great!
|
*/

//ここから
//リバースプロキシ経由のHTTP/HTTPS判定
if(array_key_exists('HTTP_X_FOWARDED_PROTO',$_SERVER) === true){ //"HTTP_X_FOWARDED_PROTO"ヘッダーが存在していたら
    if(strtoupper($_SERVER["HTTP_X_FOWARDED_PROTO"]) == "HTTP"){ //strtoupper("HTTP_X_FOWARDED_PROTO")の中身が"HTTP"だったら
        URL::forceScheme('http'); //すべてのURLをhttpに書き換える
    } else {
        URL::forceScheme('https'); //すべてのURLをhttpsに書き換える
    }
}
//ここまで

$_SERVERはPHPにおいて、サーバー情報および実行時の環境情報がすべて格納されるスーパーグローバル変数です。

$_SERVER – php.net

この中に、リクエストヘッダの中身もすべて格納されるので、その中からnginxやAmazon ALBやClassic Load BalancerがHTTP/HTTPSの情報を格納する”X_FOWARDED_PROTO”ヘッダーを参照して、どちらでアクセスされたかを判定しています。

ifを敢えてHTTPかどうかで判定している理由は万が一、”$_SERVER[“HTTP_X_FOWARDED_PROTO”]”にhttpでもhttpsでもない不正な値が入っていた場合も、とりあえずhttps://で吐き出すようにするためです。

こんな形で処理を加えてやれば、Laravelでもnginxやロードバランサーを使用していても正常にHTTPとHTTPSの切り替えが行えるようになると思います。

少しでも参考になりましたらしたら幸いです。