React.js docs読んでいるのでメモ
今改めてReact.jsを学びなおしている。
以前チュートリアルをやって分かったような分からないような気持ちだったので、ドキュメントを読んでいるが詳しく解説があって読みやすい。
以下のページから1ページずつ読んでいるのでそのメモ。h3は雑にページのタイトルだったり項のタイトルだったりする。
要素
Ractアプリケーションの最小単位の構成ブロック
React要素はプレーンオブジェクト(notブラウザのDOM要素)
要素をDOMとして描画するには
ReactDOM.render()
にelement(React要素)とHTML内の要素を渡す(document.getElementById('root')
)
DOMやHTMLとの関係がよく分からなくなったときは:
Document Object Model (DOM) は HTML や XML 文書のためのプログラミングインターフェイスです。ページを表現するため、プログラムが文書構造、スタイル、内容を変更することができます。 DOM は文書をノードとオブジェクトで表現します。そうやって、プログラミング言語をページに接続することができます
https://developer.mozilla.org/ja/docs/Web/API/Document_Object_Model/Introduction
レンダーされた要素の更新
React DOM は要素とその子要素を以前のものと比較し、DOM を望ましい状態へと変えるのに必要なだけの DOM の更新を行う
コンポーネントとprops
コンポーネント: JavaScriptの関数のようなもの。任意の入力を受け取りReact要素を返す。任意の入力はpropsと呼ばれる。
関数コンポーネントとクラスコンポーネント
クラスコンポーネント: ES6クラスを利用したもので、React.Componentをextendしrenderをオーバーライドする
コンポーネントのレンダー
ユーザー定義のコンポーネントをレンダーすることもできる。具体例は: https://ja.reactjs.org/docs/components-and-props.html
コンポーネントを組み合わせる
function Welcome(props) { return <h1> Hello, {props.name}</h1> } function App() { return ( <div> <Welcome name='Sarah' /> <Welcome name='Taro' /> </div> ); } ReactDOM.render( <App />, document.getElementById('root') );
Propsは読み取り専用
すべてのReactコンポーネントは自己のpropsに対し純関数のように振る舞わなければならない。
state とライフサイクル
「何が起こったのかをメソッドが呼び出される順序にそって簡単に振り返ってみましょう」の箇所は繰り返し読むこと。
データは下方向に伝わる
単一方向の(トップダウンの)データフロー
flex-git-configにGithub ActionsでCI/CD環境を整備した
flex-git-configを作ったが、CI/CD環境もなくバイナリも手動でリポジトリにcommitしていた。
同僚から便利じゃんって言ってもらえたのと、Github Actions使いたいと思いつつ機会がなかったので利用し導入してみた。 併せて、雑だった各種メッセージや終了時の挙動を改善した。
ちなみにflex-git-configを作成した動機は以下に書いている。 blog.ebihara99999.com
作成にあたり以下を参考にさせてもらいとても助かった。 qiita.com
Golang、あまり業務で使うことが少ないんだけどflex-git-configを盆栽にして細々とメンテしていこうと思う。
開発環境でActionController::InvalidAuthenticityTokenが出るようになった
結論
SameSite=None; Secure
にしているサービスは開発環境もHTTPS化しておきましょうというお話です。Chromeは84よりデフォルトの挙動が変わり、FirefoxもFirefox 69からSameSite属性が利用できるようになっています(デフォルトの挙動はまだのよう)。
自分の担当しているサービスでもメンバーが既にHTTPS化してくれていましたが、HTTPとHTTPS両方使える状態だったので今回の事象に遭遇してしまいました。
経緯
初回リクエスト時のレスポンスを返す際に生成したCSRFトークンがsession[:_csrf_token]
に格納され、次のリクエスト時には当該データとリクエスト時に受け取ったCSRFトークンを突き合わせリクエストの整合性を担保している。
具体的にはこのあたり。
def real_csrf_token(session) # :doc: session[:_csrf_token] ||= SecureRandom.base64(AUTHENTICITY_TOKEN_LENGTH) Base64.strict_decode64(session[:_csrf_token]) end
出典: actionpack/lib/action_controller/metal/request_forgery_protection.rb
しかし2回目のリクエスト時にはその前に生成されているはずのCSRFトークンがsession[:_csrf_token]
に格納されておらず、不正なリクエストと判定されているようだった。Safariで確認したところ想定通りのタイミングでsession[:_csrf_token]
に値が格納されていた。
自分で挙動を調査しチームメンバーにヒアリングしたところ
という状態だった。
HTTPSでログイン可能という挙動とデバッグの過程から、SameSite Cookiesの機能ではないかと疑った。 Chromeでログインできるメンバーに確認したところその人だけバージョン63のChromeを使っており、ログインできない組は64を使用していた。確認したところ、新型コロナウィルスの影響で延期されていたSameSite cookieの対応が7/14 バージョン84から再開されており、その影響であることが判明した。
参考
ActiveSupport::MessageEncryptor について調べたのでメモ
IV(初期化ベクトル)をどこに保存してあるのだろう、どうやって復号化しているのだろうか?と調べたのでメモ。
#encrypt_and_sign
の返り値は、--
区切りで暗号化データ・初期化ベクトル・認証タグとなっている(それぞれBase64符号化を行っている)。
# Rely on OpenSSL for the initialization vector iv = cipher.random_iv cipher.auth_data = "" if aead_mode? encrypted_data = cipher.update(Messages::Metadata.wrap(@serializer.dump(value), metadata_options)) encrypted_data << cipher.final blob = "#{::Base64.strict_encode64 encrypted_data}--#{::Base64.strict_encode64 iv}" blob = "#{blob}--#{::Base64.strict_encode64 cipher.auth_tag}" if aead_mode? blob
ref: active_support/message_encryptor.rb
実行結果
crypt = ActiveSupport::MessageEncryptor.new('a'*32) => #<ActiveSupport::MessageEncryptor:0x00007f9fc8fefaa0 @secret="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", @sign_secret=nil, @cipher="aes-256-gcm", @aead_mode=true, @verifier=ActiveSupport::MessageEncryptor::NullVerifier, @serializer=Marshal, @options={}, @rotations=[]> crypt.encrypt_and_sign('secret data that needs to be concealed') => "PnsLv1E/iLi0ZZxE4NKAavBO3UJc4Xe3KUZnvsJfqmA61Rt/iGPjtYbxy55/OUng--HcmSJhaaOrSoBGVL--oGfjcvq66Kw4i2Yk3A6neQ==" irb(main):054:0>
上に示したように返り値は PnsLv1E/iLi0ZZxE4NKAavBO3UJc4Xe3KUZnvsJfqmA61Rt/iGPjtYbxy55/OUng--HcmSJhaaOrSoBGVL--oGfjcvq66Kw4i2Yk3A6neQ==
となっており、--
で分解するとそれぞれ
PnsLv1E/iLi0ZZxE4NKAavBO3UJc4Xe3KUZnvsJfqmA61Rt/iGPjtYbxy55/OUng
(暗号化データ)HcmSJhaaOrSoBGVL
(IV)oGfjcvq66Kw4i2Yk3A6neQ==
(認証タグ)
となっている。
したがって初期化ベクトルをDBに保存する必要がない。以下に引用するように、実際の処理ではは encrypted_data, iv, auth_tag = encrypted_message.split("--").map { |v| ::Base64.strict_decode64(v) }
としている。ここが attr-encrypted gemとの違いで気軽に使いやすい。
def _decrypt(encrypted_message, purpose) cipher = new_cipher encrypted_data, iv, auth_tag = encrypted_message.split("--").map { |v| ::Base64.strict_decode64(v) } # Currently the OpenSSL bindings do not raise an error if auth_tag is # truncated, which would allow an attacker to easily forge it. See # https://github.com/ruby/openssl/issues/63 raise InvalidMessage if aead_mode? && (auth_tag.nil? || auth_tag.bytes.length != 16) cipher.decrypt cipher.key = @secret cipher.iv = iv if aead_mode? cipher.auth_tag = auth_tag cipher.auth_data = "" end decrypted_data = cipher.update(encrypted_data) decrypted_data << cipher.final message = Messages::Metadata.verify(decrypted_data, purpose) @serializer.load(message) if message rescue OpenSSLCipherError, TypeError, ArgumentError raise InvalidMessage end
ref: active_support/message_encryptor.rb
参考
DFSについてのメモ
競技プロでDFSの問題が出てきて調べたので主にリンクのメモ。
以下2記事の DFS (深さ優先探索) 超入門! 〜 グラフ・アルゴリズムの世界への入口 〜 がとてもわかり易かった。概念から丁寧に解説があり、図・コードも記載されているのでイメージがかんたんに湧く。言葉の説明もとても分かりやすい。
合わせてベクトルの定義を忘れていたので復習しようと思い調べたら以下の資料がとてもわかり易かった。
第1章 線形代数の基礎のキソ - 東京工業大学 理学院 数学系
あと色々調べたら以下のサイトを見つけた。ちゃんと読んでないので後で読む。
再帰難しいなぁと思っていたけど以下が参考になった。
次回のStep-to-Rails-Expert.rbについて
次回は新型コロナウィルスの影響を鑑みリモート開催とします。
以下の理由でZoom等のツールを用いずSlackのみ用いた形式で実験的に開催する予定です。
- 家庭の事情で音声を繋ぎっぱなしでの参加や映像を映しての参加が難しい方がいる
- たとえSlack上だけでも何日の何時に行けば人がいる、という状況が定期的にあると生活のリズムが取りやすくなる
僕はリモートワークで家にいる時間が多くなってしまうので、人が少ないカフェに行き第36回で開催したActiveRecordソースコードリーディング会の内容を一人でやるつもりです。
step-to-rails-expert-rb.connpass.com
コミュニケーションという側面では普段より効果が薄くなるかもしれませんが、こういう時だからこそ普段となるべく変わらず負担なく続けて行こうと思います。普段の作業の延長で気軽に参加して頂けると嬉しいです。
3/30開催予定、後日募集公開します。
インシデントハンドラプレイブックを書いている
弊社の@kurotaky さんの発案で、インシデントハンドラ虎の巻を作る取り組みをしている。その中で、 @hibomaさんにセキュリティの項の執筆について指名して頂いた。
私はセキュリティインシデント対応に際しての心構え、状況に応じた体制と役割などについて書いている。以前からこの辺の体制の話をまとめいつか書こうと思っていたけど忙しくて手つかずだったので、良い機会をもらえて感謝している。
教えて頂いた以下の資料がとても参考になった。自分の経験から考える理想的な体制や役割とこれらの資料を照らし合わせ、社のスタンダードとなるものを書きたいなと考えている。
Incident Command for IT: What We’ve Learned from the Fire Department