コードレビューは「コードの欠点を指摘する行為」ではない

コードレビューを「コードの欠点を指摘する行為」だと無意識に思っている人を見かけるけども、そういうふうに認識しないほうがチームにとって良いですよ、という話。理由は以下。

  • レビュワーの方がレビュイーよりも実力が無いといけない、という認識と結びつきがち
  • チームの若いメンバーがレビュワーになりづらくなる
  • 古株のメンバーやリーダーの書いたコードがレビューされなくなる
  • レビューで指摘された項目がない = (指摘された欠点が無いということなので)良いコードという図式になりやすい
  • レビュワーが欠点を指摘するあまり攻撃的なレビューをしてしまうことがある
  • 逆にレビュワーがレビュイーに遠慮してあまりレビューしなかったりする
  • レビュワーが誰でもわかる間違いしか指摘できなくなり、建設的な議論が起こらなくなる

コードレビューが機能不全に陥る原因の一つが、コードレビューに対する基本的な認識がずれていることだと思う。

じゃあどういう感じでコードレビューしていけばいいのかは、あとで書く(続く)

JWTをセッション管理に転用するのはあまり良いアイデアではない(認証だけならいいよ)

JWTをセッションに使うことに関して最近少し議論があったので、自分のお気持ちを表明したいと思います。

私は以前SPAを書く時にJWTをセッション管理に使おうとしたことがありましたが、仔細に検討していくとJWTをセッション管理に使うのは無意味にセキュリティ上のリスクを増やすだけで、伝統的なクッキーを使ったセッション管理を使った方が良いという結論に至りました。

前提を整理するためにあらかじめ前置きすると、「JWTをセッション管理に使う」というのは認証APIなどで返ってきたJWTをlocalstorageなどJavaScriptからアクセスできるストレージに保管しておいて、ajaxでサーバにリクエストを投げるたびにAuthenticationリクエストヘッダなどにJWTを付けて送る使い方を指します。

JWTをセッション管理に使うべきではないと思った理由の詳細は以下適当に箇条書きにします。

  • JWTをセッションに使うと、サーバー側でセッションストレージを持たなくても済むが、同じことはいわゆるクッキーセッション(クッキーにHMACで署名したデータを書き込んでセッションとする方法)でもできる
  • JWTをlocalstorageなどのJavaScriptからアクセスできるストレージに保管するのは、認証IDや署名されたトークンをhttpOnlyフラグを立てたクッキーに保管するよりもリスクが大きい
  • なぜならlocalstorageに認証トークンを保持すると、XSSがあった際に誰にも気づかれずに認証トークンを収集され続けたりセッションハイジャックされる恐れがある
  • XSSは無いに越したことはないが、だからといってXSSを経由したセッションハイジャック対策をしなくてもいい、ということにはならない
  • なぜなら、XSSは開発者のエスケープし忘れなどのポカミスによって引き起こされると認識されることがあるが、実際にはそれだけではなく、ブラウザやサーバー、言語処理系、ミドルウェアなどのバグによっても引き起こされる。最近の徳丸さんのブログに取り上げられた例では、PHPとApacheのバグを組み合わせて引き起こされるXSS(https://blog.tokumaru.org/2018/09/cve-2018-17082-cache-poisoning.html)が紹介されている。こういった事例を鑑みるに、XSSはアプリケーション開発者が気をつけてコードを書けば100%防げると断言することはできない
  • 一般的なウェブアプリケーションで、ユーザーが危険な処理をする際に、ログインしているユーザーに対して再度パスワード入力させるのは、セッションハイジャックされても致命的な被害を避けるためでもある。これと同様に、XSSがあったとしてもそれがセッションハイジャックにつながらないように対策をするのは変な話ではない。セキュリティ対策を0か1かで判断するのは明らかに間違っていると思う
  • クッキーセッションを用いると、JWTと同じようなステートレスなセッション管理ができる。クッキーにhttpOnlyフラグを付けることで、XSSがあっても認証トークンを収集されてセッションハイジャックされるというようなシナリオは防ぐことができる
  • よくよく考えるとセッションストレージを持たない完全にステートレスなセッション管理は、一般的なアプリケーション開発の要件上それほど嬉しくない。ユーザがパスワード変更する際にそのユーザのセッションを強制ログアウトさせるというよくあるユースケースを考えると、完全にステートレスなセッション管理では要件を満たすことができない。これはクッキーセッションでも同様
  • JWTでこの要件を満たすためには、JWTのjtiクレームにユニークなトークンを設定してサーバー側で失効させるjtiクレームのトークンを覚えておく必要があるだろう。結局これはサーバー側でセッションストレージのようなものを持たないといけないことになる
  • セキュリティ上のリスクが増える割には得られるものは不完全にステートレスなセッションで、しかも同じことはよりリスクを減らせるクッキーセッションでも可能である
  • こうやって見ていくと、JWTをセッション管理に転用するのは無意味にセキュリティ上のリスクを増やしているだけのようにしか見えない

普通のセッション、クッキーセッション、JWTによるセッションというこれらの選択肢を見てみると、セキュリティ上一番割に合わない選択肢がJWTを使ったセッション管理で、わざわざこれを選択するのはよっぽど何か特殊な要件があったりする場合かなあという感じになりました。こちらからは以上です。

最新のウェブフロントエンド技術を無理してキャッチアップする必要はない

ウェブフロントエンド技術は変化が激しいと言われるけれども、多くの人にとって最新のウェブフロントエンド技術を無理してキャッチアップする必要は無い。以下理由。

  • ここでいう最新のウェブフロントエンド技術とは、新しいブラウザのAPIや新しいJavaScriptの文法や新しいフレームワーク・ツールなどを指す
  • 今のHTML5はドキュメントを表現するプラットフォームだけではなくアプリケーションプラットフォームとしても機能するように進化をしている最中
  • だからアプリケーションプラットフォームとしての進化を支える新技術がたくさん出てきている
  • 逆に言うと、アプリケーション(SPAとか)を書かない人にとってはキャッチアップする必要の無い場合がたくさんある
  • また、それらのウェブフロントエンドの新技術を全てキャッチアップするのは基本的に不可能だと思う
  • 自分はウェブフロントエンドやそれのパフォーマンスを専門の一つにしているけれども、WebRTCやWebGLの詳しい話をしろと言われてもできない
  • 基本的にウェブサイトにちょろっとJavaScriptを書いてるような人は新しい技術やフレームワークを沢山キャッチアップする必要はあまりない
  • AngularやReactや最近のフレームワークやツールなど、SPA開発を念頭に置いていることが多い
  • SPA書かない人がSPA書くための技術をキャッチアップしてもしょうがない
  • JavaScriptの新しいAPIや文法は互換性を念頭において設計されている
  • 古いと言われるコードや書き方であっても仕様として非推奨になったわけではないからそのまま利用できる
  • ウェブブラウザの開発者は昔ながらの書き方をしても壊れないように互換性を大事にしているので、それに乗っかっても罪悪感を感じることはないと思う
  • JavaScriptが使われるユースケースは五年前十年前に比べると格段に増えた
  • 昔はウェブサイトにちょっとしたインタラクションを実装するのに使われていただけだった(例えばカーソルに追従する星を付けたり)
  • 今は違っていて、 ウェブ上で動くGUIみたいなリッチなSPAも、Electronで動くクロスプラットフォームなデスクトップアプリも、Cordovaで動くHTML5モバイルアプリも、React Nativeで動くモバイルアプリも、Node.jsで動くサーバアプリケーションも、Node.jsで動くコマンドラインアプリケーションも全てJavaScriptで書ける
  • これらの新しいユースケースに対応するために新しいツールやフレームワークも当然出てくるし、必要とされる知識も変わってくる
  • ウェブサイトにちょっとしたインタラクションを付け加えるためにJavaScriptを書くというユースケースは、それがJavaScriptの唯一のユースケースだった頃に比べるとそれほど大きなユースケースではない
  • 専門でJavaScriptを書いているような人はある程度キャッチアップする必要は当然ある
  • しかしそうではない人が無理して新技術をキャッチアップする必要は無い。なぜなら想定されているユースケースがあまり被っていない場合が結構あるから
  • 片手間でJavaScript書いてる人がjQuery使って昔ながらのJavaScriptのコード書いてても、ウェブサイトにちょろっとインタラクションを付け加えるだけならそれなりに機能するので別にそれでいいと思う
  • 新技術に興味が持てなければ、自分の仕事にとって必要なものだけをキャッチアップすればよい
  • それがわからないのに闇雲に新技術をキャッチアップしなければいけないと思っている人は、自分を見失っている

こちらからは以上です。

ウェブパフォーマンスの最適化のためにできる事は何か、もしくは『Webフロントエンド ハイパフォーマンス チューニング』という本を書いたという話

Webフロントエンド ハイパフォーマンス チューニング

Webフロントエンド ハイパフォーマンス チューニング

技術評論社さんから『Webフロントエンド ハイパフォーマンス チューニング』を出版することになりました。題名通り、フロントエンド周りのウェブパフォーマンスについて書いた本です。

ウェブパフォーマンスというのは、昔はウェブページの初回の表示の速さのみを指すものでした。インタラクションを持たない静的なウェブページがほとんどであった頃には、一度ウェブページを表示し終わってからはパフォーマンス上の問題が発生することが比較的少なかったからです。ウェブパフォーマンスを改善するチューニングテクニックというのもこの初期のリソースの読み込みを改善するものが主でした。このようなテクニックは、『ハイパフォーマンスWebサイト』で語られている「ファイルをgzip圧縮して配信する」「DNSルックアップを減らす」「JavaScriptとCSSは外部ファイル化する」などが代表的なものです。

この状況は、複雑な振る舞いを持つウェブアプリケーションが登場する事で変わります。JavaScriptによる動的な振る舞いを持つウェブページでは、一度レンダリングが終わってからもユーザのアクションに応じてインタラクションを行う必要があります。その時に問題になるパフォーマンス上の問題とは、従来のリソースの読み込みに関する問題ではなく、JavaScriptやDOM操作の実行速度の問題であったり、CSSセレクタのマッチング速度の問題であったり、視覚的要素のレイアウトや描画の速度の問題であったりします。これらの新しく出てきたパフォーマンス上の問題は、これまで紹介されてきたリソースの読み込みの速度をチューニングするテクニックでは全く対応できません。例えば、アニメーションの描画をなめらかにするために初期表示のパフォーマンスの最適化を行っても意味が無いことは直感的にわかると思います。

こういった新しく登場したパフォーマンス上の問題を解決するには、ウェブパフォーマンスという言葉の意味を捉え直し、かつそれらの問題が起きる根本的な原理であるブラウザのレンダリングの仕組みを把握し、レンダリングの工程ごとに発生する異なる問題を解決するためのチューニングテクニックを正しく適用することが必要です。この本では、ウェブパフォーマンス上の解決すべき問題をGoogleが提唱しているパフォーマンスモデルであるRAILに添って説明しています。その上でブラウザのレンダリングの仕組みやウェブパフォーマンスの計測方法や様々なチューニングテクニックを紹介しています。この本では今現在のウェブパフォーマンスを扱う上で必要になる基礎知識やチューニングテクニックを体系的に解説しており、ここまでウェブパフォーマンスについて網羅した技術書は、日本語の書籍の中では現時点ではこの本だけです。

すでに書店などには並んでいるのでウェブパフォーマンスに関心のある方は一度手に取って読んでみて下さい。というわけで『Webフロントエンド ハイパフォーマンス チューニング』の宣伝エントリでした。

MastodonはP2Pではないという話、もしくはMastodonの脱中央集権の仕組みについて

Fukuoka.php vol22にてMastodonについて話してきました。

Mastodonは最近盛り上がってる分散型SNSですが、その仕組みに興味をもったので調べてみたのが今回の話になります。スライドの中で主に説明しているのは、Mastodonが実装している分散型SNSを実現するためのプロトコルOStatusについてです。

OStatusはAtomフィードを核とした仕様です。ユーザーのつぶやきをAtomフィードで表現し、さらにそれをコンタクト情報を形式化するPortable ContactsとSocial Network上の活動を形式化するActivity Streamsで拡張しています。フィードだけだと、リモートのサーバはポーリングする必要があるため、それを補うためにPubSubHubbubでAtomフィードの更新をほぼリアルタイムに受け取ることができるようにしています。また、FollowやFavやReplyやRetweetを相手先に通知するためにはSalmonを使っています。リモートフォローする際に入力する(ID)@(Mastodonのドメイン)という文字列からそのユーザーの情報を取得するためには、WebFingerを使っています。

日本国内ではP2Pと結び付けられて語られることのあるこのMastodonですが、こうやって見てみるとP2Pとはあまり関係がなく、フィード関係のプロトコルを使って分散型SNSを構築できる仕組みであることがわかると思います。

HTML5とか勉強会にて「大量の要素を高速に表示するバーチャルレンダリング入門」という題で話をした

第68回HTML5とか勉強会にて「大量の要素を高速に表示するバーチャルレンダリング入門」という題で話をしてきました。

ブラウザのレンダリングは、基本的にそのドキュメントに含まれるDOM要素の数が多ければ多いほどレンダリングが重たくなります。バーチャルレンダリングというのは、JavaScriptでDOM要素の数を調整して見えない部分の描画をうまくサボる仕組みです。

バーチャルレンダリング自体は結構いろんなところで利用されているにもかかわらずその仕組みやアルゴリズムの流れについて日本語での解説をあまり見かけなかったので、HTML5とか勉強会ではこれについて話すことにしました。

このテクニックは結構昔からあるテクニックで、知ってる人は知っているけれども知らない人は知らないままという感じになりがちなんですが、今回はHTML5とか勉強会という参加者が比較的大きな勉強会(180人ぐらい参加してる)で話せて良かったなと思いました。