ninjinkun's diary

ninjinkunの日記

iPhoneの英語入力キーボードを開発したプログラマーの話『Creative Selection』を読んだ

Appleファンとして、プログラマーとして、とても面白く読んだ。

KHTMLをベースにWebKitを作り始める話、iPhoneプロジェクトに入って英語入力キーボード開発のDRI*1になる話など、今自分がMaciPhoneで使っているソフトウェアの話が多く、具体的なイメージを持ちながら楽しむことができた。

Apple社内の雰囲気や体制が垣間見えるエピソードが多く、なるほどこういう環境でWebKitiPhoneは開発されていたのかと産業遺産を見るような気持ちで読んでいた。

  • とにかくデモを作って見せる文化
    • 上司にデモを見せる、気に入られると段々見せる階層が上がっていって、最後はジョブズにデモを見せるようになる
    • 動くものがなかなか出てこないと不信感を持たれる
  • (特に明言はされていないが)Appleにはコアロジックからアニメーションまで実装できるプログラマーが多数在籍していそうな雰囲気
    • 著者はブラウザの実装ができるくらい実力があるプログラマーだが、アニメーションまで実装している
      • 昨今ではデザインエンジニアとかテクニカルクリエイターとか呼ばれる人材ではなかろうか
    • こういった人たちが多数在籍し、彼らが動きの提案を作って、その中から良い物を選び取って製品が作られている様子
      • iPhoneは最初のバージョンからUIに相当な説得力があったが、こういうチームで作られてたのだと聞くと納得感がある
    • Directorを使ってインタラクティブなモックを作るデザイナーも居て、彼らも動きを作って提案を出しまくる

ジョブズ時代のApple社内の雰囲気を垣間見られる本としておすすめ。技術用語や実装の話もある程度入っているので、プログラマーなら楽しさ倍増かもしれない。

Creative Selection  Apple 創造を生む力

Creative Selection Apple 創造を生む力

*1:Direct Responsible Individual 直接担当責任者 プロジェクトには必ず1人の責任者を置くというApple用語

Real World HTTPミニ版はいいぞ

www.oreilly.co.jp

mozaic bootcampに参加する前に予習としてReal World HTTPミニ版を読んでいったのだが、これが非常に良い本で役に立った。

HTTPの歴史を俯瞰しながらプロトコルの詳細を解説してくれる流れになっているので、自分のようにWebアプリケーションを作るために個別のトピックはなんとなく知っているけれど、策定の経緯や相互の繋がりを知らない人間には、知識を補完してくれる内容でありがたかった。

目次は以下の通りだが、既に仕事をしている人は4章までが対象かと思う。5章は新人のWebエンジニア向けの内容になっている。

  • 第1章 HTTP/1.0の世界:基本となる4つの要素
  • 第2章 HTTP/1.0のセマンティクス:ブラウザの基本機能の裏側
  • 第3章 HTTP/1.1の世界:高速化と安全性を求めた拡張
  • 第4章 HTTP/2とHTTP/3の世界:プロトコルの再定義
  • 第5章 ウェブアプリケーションの基礎

実は後からミニ版ではないフル版も買って読んだのだが、まとまり具合、読みやすさはミニ版の方が良いと感じてしまった(もしこれを著者の方がご覧になることがあったらすみません)。

無料でこれだけの内容が提供されているのにも驚くが、研修などで使う想定で出版されたと前書きには書かれていた*1。自分も社内勉強会などで活用していきたい。

電子版のみなので、mobiでダウンロードしてKindleアプリで通勤時などに読むとちょうど良いかと思われる。

ミニ版で全体の流れを掴んで、気に入ったらフル版も買いましょう。

*1:これは特に書かれてはいないが、インターネットに関わる知識はインターネットに還元したいという意図もあるように自分は感じた。

白金で聞こえた会話

女「お久しぶりです。」

男「お久しぶりです。僕のこと覚えていてくれてありがとう。」


男「お酒飲まないの?」

女「飲まないんです。○○症で。」

男「じゃあ僕も今日はジンジャーエールで。」


男「アメリカに住んでたの?」

女「アメリカの大学に行っていたので、卒業してそのまま働いていました。」


男「○○さんのFacebook見た?」

女「見ました。ホントにあんなことあったんですか?」


男「前妻が〜」

東京カレンダー2018年12月号

東京カレンダー2018年12月号

アゴタ・クリストフの『悪童日記』から始まる三部作を読んだ

以前rebuild.fmでNさんがおすすめしていたので気になっていたアゴタ・クリストフの『悪童日記』を読んだ。面白すぎて、続く『ふたりの証拠』『第三の嘘』も一気に読んでしまった。

フィクションだが、第二次大戦中と戦後のハンガリーという舞台が凄まじく、暴力と死が身近にある暮らしが淡々と語られる。国境や隣国という概念があるのも、島国で育った人間から見ると新鮮に感じた。

母国に居られなくなって国を出て行ったり、友人や身内と離ればなれになるというのはどれだけ辛いことなのだろう。戦争や治安的な理由で日本から出て行かざるをえない状況を考えるだけでも、かなりしんどいものがある。

悪童日記

悪童日記

ふたりの証拠

ふたりの証拠

第三の嘘

第三の嘘

暴力沙汰を起こした警官になって追われる夢

朝起きて書き留めたのだけれど、後から読むと自分でも全くなんだかわからない。


自分は現役の警官で、交番に勤めている。 どうもコミュニケーション能力に難があり、頭も余り良くないが心は優しくて正義感はあるという設定。

かくまってくれた女性となぜか逃げる。 女性はトラウマがあり、それがどうもこの会場で結婚式を挙げる人と関係があるようだ

誓いの言葉が聞こえてきたとき、女性が取り乱し大声を上げてしまう。 自分は必死で宥めるが、途中で人が来る気配を感じて外に逃げる。 女性の友だちたちが「もしかしてと思ったら来てくれてたのね」みたいに女性に近寄るが、女性は叫びながら泣き続けている。

自分は外に出て逃げつつあるが、取り乱した女性が足を滑らせて川に落ちてしまう。 みんなも川を追いかけるが、流れが早くて追いつけない。

見かねた急流に飛び込んで追いかける。 マリオみたいに急流をぴょんぴょん飛んで、ようやく捕まえることができた。

派出所の隠れ家に帰るが、帰り道をつけられたようで、特に親しくない昔の同級生が隠れ家にたどり着いて、そこで万事休すとなる。記者会見を1時間後にやることにする。

リバーズエッジ。 オザケンが流れる。 自分は記者会見の準備をして終わる。

数年後

整形外科の医師を探す。 うまく見つかる。 女の子が自分の顔を見つけることができて終わった。

mozaic bootcampに参加して気づいた、自分に欠けていたWeb技術の知識メモ

mozaic bootcampとは?

mozaic.fmリスナー向けの勉強会。mozaic.fmはJxck氏が主催するPodcastで、Web標準やブラウザ、プロトコルなどWeb技術をターゲットにしており、自分も愛聴している。

今回行われたbootcampはゴールデンウィークの4日間を使い、「Webを正しく理解し、正しく使う」ことを目的として行われた。

参加者はざっくり言うとそこそこ経験のあるWebエンジニアが6名、主催のJxck氏、mozaic.fmでお馴染みの矢倉氏の計8名。参加にあたってはビデオ通話による選考もあった。

会場は自分が所属する一休のリフレッシュスペースを利用した。

当日どんな感じだったかは、以下のエントリで紹介されている。

主催のJxck氏のエントリ

参加者のisyumi_net氏のエントリ

自分に欠けていたWeb技術の知識

自分はWebに関わるエンジニアとして一応10年間働いてきたが、このbootcampに参加して自分がWebの基本的なことを全然理解していなかったことに気づいて愕然とした。なんとなく知っているつもりでも、人に説明できるほど理解していないことが多かった。

しかし今回のbootcamp参加で自分の穴に気づくことができ、ある程度知識を埋めることができたので、特に自分が理解してなかったトピックについて当日のメモを書き出し、まとめてみようと思う。あくまで自分のメモで、何か新しい発見があるわけではないことはお断りしておく。

  1. Cookie
  2. Cross Origin Resource Sharing (CORS)
  3. TLS

1. Cookie

  • サーバがSet-Cookieヘッダを付与すると、ブラウザは次回のアクセス時もその値を返す
    • クレデンシャルとして広く使われている
  • 有効期限について、Expire はローカルで時計を弄られる可能性があるので、今は Max-Ageを使う
  • Max-Ageがないと自動的にSession Cookieになる
    • SessionはUA依存だが、だいたいはブラウザのタブを閉じるまで
  • Max-Ageが設定されていても、Cookieはブラウザの都合で消されたりするので、必ず保存される保証はない
  • 最近はMax-Ageを長めにする傾向にある
  • Domain属性はあまり使わない方が良い

  • Pathはだいたい/だけ指定する
    • Pathを指定しないと、そのcookieを発行したpath以下でしか値が読み出せない
      • 例えば/loginで付与すると /login/hogehogeなどでしか読み出せず、/では読めなくなってしまう
  • Secure, HttpOnly は設定しておくこと
    • Secure HTTPSでのみ送信
    • HttpOnly JSから弄れなくなる
  • Clear-Site-Data `Clear-site-Data: "*"` とか指定するとログアウト時に全部消してくれる
    • Edge, Safariはまだ未対応
    • 今までは明示的に消す仕組みがなかった
  • クレデンシャルとして使われているのに、セキュアに使うのが難しいデザインになってしまっているのがCookieの問題点
  • SameSite属性
    • CookieはSame Origin Policyの範疇外の困った子なので、これをまともにする
    • 既存の挙動を変えるとサイトが壊れるので、新しいattributeで対応する
    • SameSite: Strict;
    • SameSite: Lax;
      • トップレベルナビゲーションとサイト内だけでcookieが送られる
      • 使いやすい
    • CookieをRead cookieとWrite cookieに分けるのが望ましい
      • そしてWrite cookieにStrictを付けるのが一番いい
  • Secが付いているヘッダーはJSから付与できない
  • 話はこの後Intelligent Tracking Prevention (ITP) に展開したが、割愛

2. Cross Origin Resource Sharing (CORS)

  • xhrで他サイトにリクエスト送信が可能になったが、他サイトにリクエストする際にCookieやヘッダも一緒に送られてしまう
    • 他サイトの情報を無制限に読み取り可能
  • xhrでリクエスト可能な範囲をOriginという概念で制限する
    • scheme、host、portが一致しないと別originとして扱われ、リクエストが制限される
  • Access-Contol-Allow-Origin
    • 指定したOriginからのリクエストを許可する
    • 同一組織内の別サービスからの読み出しなどで使う
    • POST/PUT/DELETEなど副作用があるメソッドを投げる場合は、OPTIONSでpreflightリクエストを投げる
  • Formは遷移するので他のサイトにCORSもできる。originヘッダでどこから来たかわかる
    • Formが自分のサイトから来たものかを検証しないとCSRFになる

3. TLS

このトピックは最終日に時間が余っていたので、自分がリクエストした。いきなりJxck氏がXORについて話し始めて面食らったが、どんどん話が展開し、「この人TLSの仕様が頭に入ってるんだ…」とみんな唖然としていた。後から聞いたら自分で実装したことがあるとのこと。

  • XORは2回かけると元に戻る性質がある
    • A ^BB=A`
    • 共通鍵暗号の基本はこれ
    • 暗号化、復号化コストが低い
    • このBを共通鍵としてクライアントとサーバー間で共有して暗号化された通信をするのがTLSのざっくりした説明
  • TLS 1.2のハンドシェイク
    • 公開鍵暗号を使って共通鍵暗号の鍵を交換する
    • ClientHello
      • クライアントから必要な情報を渡す
      • 対応している暗号化方式を送信
    • ServerHello
      • 暗号化方式を決定して送信
    • ServerCertificate
    • ServerKeyExchange
      • サーバーの公開鍵を送信
    • CertificateRequest, ClientCertificate, CertificateVerify
      • クライアント証明書関係、略
    • ClientKeyExchange
      • サーバーの公開鍵でクライアントが生成した共通鍵を暗号化して送信
    • ChangeCipherSpec
      • ここから共通鍵を使った暗号化通信に移行する
  • なぜ認証局が必要か?
    • サーバーが送信してくる公開鍵がサーバーの運営者のものであることを保証するため
      • 中間者攻撃により通信経路が乗っ取られて、偽の公開鍵が送られていても署名で検証できる
      • 所謂オレオレ証明書をクライアントが許可して運用していると、中間者攻撃で証明書をすり替えられても本物かどうかを検証できなくなる
  • 認証局はさらに上位のルート認証局に認証されており、ルート認証局ルート証明書はOSやブラウザにインストールされている
    • これにより、ルートを辿っていって最後はローカルにインストールされている証明書で検証することで、CAの正当性を保証できる

終わりに、お気持ちの表明

bootcampではもっと膨大なトピックが扱われていたが、特に自分に欠けていたと感じたものを抜粋して書き出した。

自分は、bootcampのテーマである「Webを正しく理解し、正しく使う」とは、技術の様々な文脈や経緯を知った上でベストプラクティスを選択できることであり、その選択理由を明確に説明できることだと解釈した。

だが、bootcampを通して、Webを正しく使うことは本当に難しいし、Web開発者の全員にこれを求めるのは無理だろうと感じた。昨今ではフレームワークやPaaSがベストプラクティスを実装して、我々利用者は難しいことを意識しなくても、ある程度のセキュリティやアクセシビリティを担保しながら開発できるようになってきているという現状もある。

しかしそれでも、ある程度人数が居る開発組織ならば、少なくとも一人はWebを正しく使えるエキスパートが居るべきだと思う。自分が知っている「技術力がある」と見なされている会社には、そういったエキスパートが数人、もしくはもっと多く在籍している。

今回こういった機会を得たことで、一介のWebアプリケーション屋である自分も、「Webを正しく使えるWebアプリケーション屋」と名のれるようになりたいと強く思った。

Jxckさん、矢倉さん、参加者の皆さんありがとうございました。今後もmozaic.fm聞き続けます。

mozaic.fm

create-react-app 3.0にしたのでついでにTSLintからESLintに移行した

経緯

BlogFeedbackで使っているcreate-react-appを3.0に上げたらTypeScriptにもLintが効くようになっていたが、そのせいでいきなりビルドが止まるようになってしまった

  • 元々TSLintを入れてエディタとCIでTSLintを実行していた
  • create-react-app 3.0からyarn startyarn buildESLintが実行される
    • TypeScriptには@typescript-eslintで対応してるみたい
  • 新しく入ったESLintは無設定状態だとデフォルトのルール (eslint-config-react-app)で実行されるので、TSLintで設定していなかったいくつかのルールで引っかかるようになって、CIでyarn buildが止まっていた
    • eslint-config-react-appにはjsx-a11y react-hooks プラグインが入っていたので、その辺で落ちていた
  • 今後はESLintになる流れらしいので、この際なのでESLintに移行して、ルールもデフォルトに合わせることにした

ESLint対応

github.com

prettier対応だけして、あとはデフォルト。

$ yarn add eslint-config-prettier eslint-plugin-prettier

.eslintrc.json

{
  "extends": [
      "react-app", 
      "plugin:prettier/recommended"
  ]
}

package.json

scripts: {
    "eslint": "eslint './src/**/*.{ts,tsx}'",
    "eslint:fix": "eslint --fix './src/**/*.{ts,tsx}'"
}

あとはCIでtslint使ってる箇所を書き換えて終わり。

ブラクラ

const SignInPage: React.FC<Props> = props => {
  useEffect(() => {
    props.fetchUser(firebase.auth());
    return () => undefined;
  }, []);
  ...
}; 

というhooksをよく知らずに書いたコードで怒られたのでeslint --fixしたら

const SignInPage: React.FC<Props> = props => {
  useEffect(() => {
    props.fetchUser(firebase.auth());
    return () => undefined;
  }, [props]);
  ...
}; 

にされて、effectが無限に発火し続けてブラウザが固まるようになってしまった。 リリースしてから気づいたので焦って直した(fetchUser をキャプチャするようにしたら直った)。

おわりに

create-react-app 使ってると最新のベストプラクティスが勝手に突っこまれるので便利。その反面アップデート時の対応は毎回少し面倒。

毎朝空いている有楽町線下りの考察

東京の電車は混んでいて辛いという話を聞くが、自分が通勤で使っている有楽町線の東側から西側(新富町→永田町)へ向かう下り電車はかなり空いている。9:30くらいの電車ではほぼ座ることができ、早めに出勤しても1、2駅立っていればだいたい座れる。

なぜこんなに空いている電車が走っているのか考えてみた。

  • 有楽町線は西側で西部、東武と相互乗り入れしており、郊外からの乗客が多い
    • このため、朝の時間は10両編成車両が4, 5分おきにやってくる
  • 一方で東側は新木場でJRに乗り換えられるだけ
    • かつ接続する京葉線の乗客はほぼ乗り換えずに東京駅に向かうと思われる
    • 沿線の住宅地も月島、豊洲くらい
  • 鉄道はやってきた車両を車庫に戻す運用が必要なので、どちらかの列車本数を減らすことはしづらい

つまり人数が多い西側の乗客を運ぶためのキャパシティで人数が少ない東側の乗客を運んでいるので、ガラガラになっているわけだ(とドヤ顔するほどのことでもない)。

もちろんこの状態では経営効率が良くないことは明らかなので、有楽町線豊洲-住吉間に支線を作って延伸する計画が進行中らしい。

他にも片側だけ相互直通がない路線がないか調べてみたが、あったのは都営新宿線の東側くらいで、こちらは郊外まで地下鉄自体が伸びていた。

Mini Metroというゲームをやっていると、こういうことを延々考えてしまうのでおすすめです。

ミニメトロ

ミニメトロ

  • Dinosaur Polo Club
  • ゲーム
  • ¥480

play.google.com

Suica入りスマホ2台持ち生活

  • Suica契約済みのiPhoneSuica未契約のPixel 3を持ち歩いていた
  • 通勤で改札の前に来る度にPixelを取り出しまい、ああ違ったiPhoneじゃないとなっていた
  • PixelもSuica契約すればダブルSuicaで最強!と思ってPixelもSuica契約した
  • 今度は改札を出る際に、あれどっちのSuicaで入ったっけ?となって問題が余計面倒になった