Tech Racho エンジニアの「?」を「!」に。
  • Ruby / Rails関連

週刊Railsウォッチ: Railsフラグメントキャッシュ経由の情報漏洩に注意ほか(20230803後編)

こんにちは、hachi8833です。

週刊Railsウォッチについて

  • 各記事冒頭には🔗でパーマリンクを置いてあります: 社内やTwitterでの議論などにどうぞ
  • 「つっつきボイス」はRailsウォッチ公開前ドラフトを(鍋のように)社内有志でつっついたときの会話の再構成です👄
  • お気づきの点がありましたら@hachi8833までメンションをいただければ確認・対応いたします🙏

TechRachoではRubyやRailsなどの最新情報記事を平日に公開しています。TechRacho記事をいち早くお読みになりたい方はTwitterにて@techrachoのフォローをお願いします。また、タグやカテゴリごとにRSSフィードを購読することもできます(例:週刊Railsウォッチタグ)

🔗Rails

🔗 フラグメントキャッシュ経由の情報漏洩に注意


つっつきボイス:「thoughtbotの記事です」「権限によって表示内容が変わるときなどにキャッシュを経由して重要な情報が漏洩する可能性については、フラグメントキャッシュに限らず注意が必要ですね」

uncacheable!で明示的にキャッシュしないようにする機能があるのか↓」「APIドキュメントによると、キャッシュを参照しようとした時点でUncacheableFragmentErrorエラーを発生するんですって」「raiseするとは強い」「ヘルパーメソッドの結果をフラグメントキャッシュに乗せたくないときに便利、なるほど」「重要な情報を扱うときに使うとよさそうな機能👍」

# 同記事より
  <% # app/views/products/_product.html.erb %>
+ <% uncacheable! if admin? %>
  <div id="<%= dom_id product %>">
    <h2><%= product.name %></h2>
    <p>
      <strong>Price:</strong>
      <%= product.price_in_cents.to_fs(:currency) %>
    </p>
    <% # data intended for admins only %>
    <% if admin? %>
      <p>
        <strong>Wholesale price:</strong>
        <%= product.wholesale_price_in_cents.to_fs(:currency) %>
      </p>

      <p>
        <strong>Supplier:</strong>
        <%= product.supplier %>
      </p>
    <% end %>
  </div>

参考: Rails API uncacheable -- ActionView::Helpers::CacheHelper
参考: § 1.3 フラグメントキャッシュ -- Rails のキャッシュ機構 - Railsガイド

「条件付きでキャッシュしないようにするcache_unlessはよく使われますね↓」「指定し忘れに注意」

# 同記事より
<% @products.each do |product| %>
- <% cache product do %>
+ <% cache_unless admin?, product do %>
    <%= render product %>
  <% end %>
<% end %>

参考: cache_unless -- ActionView::Helpers::CacheHelper

🔗 Rodauthの認証機能は優秀(RubyFlowより)


つっつきボイス:「Jeremy Evansさんが作った認証gemであるRodauthを検証した記事です」「Rodauthを絶賛していますね」

jeremyevans/rodauth - GitHub

Ruby: 認証gem「Rodauth」README(更新翻訳)

「認証機能はDevise gemやDoorkeeper gemが広く使われているせいか、Rodauthを認証に使った日本語記事をまだあまり見かけませんね」「Deviseはメジャーかつ実績を積んでいるということ以外のメリットがあまりないし、Deviseでつらい思いをしたこともよくあったけど、でも認証gemはそのメリットがとても重要なんですよ」「そこですよね」「Rodauthは開発も活発でだいぶ高機能になっているようですし、新規のRails案件ならDeviseやDoorkeeperにこだわらずにRodauthを使ってみてもいいかも👍」

heartcombo/devise - GitHub
doorkeeper-gem/doorkeeper - GitHub


なお、最近Rodauth-rails gemのREADME翻訳に原文更新(パスキー対応など)を反映しました↓。

Rails: 認証gem ‘rodauth-rails’ README(翻訳)

🔗 Shale: 多機能オブジェクトマッパー&シリアライザ(Ruby Weeklyより)

kgiszczak/shale - GitHub


つっつきボイス:「シェールガスのShaleと同じスペルなんですね」「オブジェクトマッパーとシリアライザを両方兼ねているRuby用ライブラリか: こうやってマッパーを作る必要があるらしい↓」「XML、JSON、TOML、YAMLに対応しているんですね」「XMLはどこまでやれるかわからないけど、JSON、TOML、YAMLあたりは普通に使えそう👍」

# www.shalerb.orgより
require 'shale'

class Address < Shale::Mapper
  attribute :street, Shale::Type::String
  attribute :city, Shale::Type::String
end

class Person < Shale::Mapper
  attribute :address, Address
end

person = Person.from_xml('<person></person>')
person.address = Address.new(street: 'Oxford Street', city: 'London')

puts person.to_xml

「ところで、この手のライブラリにありがちですけど、ものすごく複雑で特殊なXMLを扱おうとすると通用しないことがあったりしますよね」「そうそう、XMLだと起きがちなんですよ😢」「XMLは闇深くなりがち」

「XMLデータは"特定の属性にこれがあるとこういう挙動になる"みたいな重箱の隅的な仕様になっていることが割とありがち」「属性にいろんな意味がこっそりあったりしますよね」「古いXMLライブラリが今も使われているのは、そういう微妙すぎるXMLも頑張れば何とか扱えるからという理由もあるんですよ」

「XMLの仕様をこちらで作れればまだいいんだけど、そうでないとつらくなりがち」「手書きで作ったようなXML仕様とかですね」「そういうのはJSONやYAMLだと表現不可能だったりする」「書き出すのはまだ何とかやれても、読み込もうとするとものすごく大変だったりしますよね」

「スキーマがあってもだめなんでしょうか?」「XSDなどのスキーマがあっても、データを通そうとするとうまくいかなかったりするんですよ😭」「一見どちらの要素を使ってもいいように見えても、実はXSDで片方のみに制限されてたりとか」「そういう理由でXMLライブラリを変更しなければならなくなったりすると悲しい...」

参考: XML Schema(XSD)とは - 意味をわかりやすく - IT用語辞典 e-Words

🔗 Rails edgeでCIを回し始めた話

つっつきボイス:「Rails 7.1になる予定のRails edgeでCIを回していろんなエラーを見つけた記事です」「可能ならこういうところにコストをかけたい」「正式リリースされる前にチェックできるといいですよね」「この間取り上げた、Rails 7.1で使えなくなるカラム名(ウォッチ20230622)や、create_associationの挙動変更(ウォッチ20230721)などもCIでキャッチしたんですね」

🔗 Railsガイドが過去バージョンも表示可能に

「おなじみRailsガイドが、6月から過去バージョンも無料で表示可能になった🎉」「Railsガイドの協賛プランに参加いただいている協賛企業のおかげです🙏」「Railsはこうやって新しいエンジニアを増やすための環境が整っているのが強みですね」

🔗Ruby

🔗 YJITの高速化


つっつきボイス:「YJITを高速化するコミットがRubyのmasterにマージされた🎉」「CRubyでYJITをオンにすると64.8%高速になる、すごい」「Rubyコミッターのk0kubunさんがShopifyに移ってもう1年なんですね」

sendopt_send_without_blockinvokesuperinvokeblockのインストラクションは、現在のベンチマークやproductionアプリケーションが終了する理由として最も多い(YJITがこれらを最適化する方法を知らない場合にside-exitするため)。

このプルリクは、YJITを変更して、そのようなシナリオでインタープリタの実装を呼び出すようにする。これにより、実行がJITコード内にできるだけ長く留まるようにする。

railsbenchのratio_in_yjitが92.6%から97.1%に改善した。
同PRより

🔗 vscode-rubocop 0.4.0リリース


つっつきボイス:「rubocop -xをLanguage Serverで使えるようになったんですって」「rubocop -xはLayout copだけをかけるオプションですね」「rubocopは大規模プロジェクトだと結構重くなりがちなので、Language Serverで軽く動かせるのはありがたい」

参考: RuboCop as a formatter -- Basic Usage :: RuboCop Docs

🔗 その他Ruby

つっつきボイス:「Rubyパーサー強者たちの対談がむちゃくちゃマニアックで個人的に大好きです」「RubyパーサーのBisonを倒した話とか盛りだくさん」「これは後で読もう👍」

Rubyパーサーを一新するYARPプロジェクトの全容と将来(翻訳)

RubyにlramaがマージされてBison依存がなくなった(RubyKaigi 2023)


つっつき後に気づきましたが、vol.1とvol.3もとても面白そうな記事です↓。

参考: 正規表現とは何なのか、makenowjustが正規表現に興味を持ったきっかけ。深掘りRubyKaigi 2023 with spikeolaf & makenowjust 文字起こしレポート vol.1 - STORES Product Blog
参考: 正規表現のPrettier、パーサに取り組むために読んだ本、RubyKaigi 2023で面白かった発表。深掘りRubyKaigi 2023 with spikeolaf & makenowjust 文字起こしレポート vol.3 - STORES Product Blog

🔗クラウド/コンテナ/インフラ/Serverless

🔗 パスキーをYubiKeyなどのハードウェア認証デバイスで使う場合の注意


つっつきボイス:「本日お休みのすろっくさんが見つけた記事です」「保存できる鍵の個数がハードウェア認証デバイスによって異なるのはまだしも、CTAP2.0仕様のハードウェア認証デバイスだと一度保存した鍵を変更・削除できないのか↓」

クライアント側に鍵を保存することで、パスワードだけでなくIDの入力も不要にすることが可能ですが、鍵の保存スペースを確保する必要があります。ブラウンさんによると、ハードウェア認証デバイスにおいて鍵の保存スペースは非常に貴重とのこと。例えばYubiKeyの場合、20個から32個の鍵しか保存することができません。

さらに、クライアントとハードウェア認証デバイス間の通信の仕様である「Client to Authenticator Protocols(CTAP)」のどのバージョンをサポートしているかによってさらに厄介な問題が発生します。CTAP2.1PREやCTAP2.1をサポートしているハードウェア認証デバイスであれば、内部に保存されている鍵を更新したり削除したりすることが可能ですが、CTAP2.0仕様のハードウェア認証デバイスの場合は一度保存した鍵を変更・削除することが不可能です。

「推測だけど、保存した鍵を変更可能にする場合のリスクを避けるための仕様なのかな?」「ここに気づかないまま動作確認を繰り返しているうちに使えなくなってしまったりしそう」「少なくともYubikeyはそういう仕様になっているのね」「鍵デバイスのストレージ容量の上限で思い出したけど、Suicaでも使われているFeliCaは、保存できるデータ容量に限りがありますね(このストレージを使うことはあまりなくて、FeliCaのIDだけを使う方が多いですが)」

参考: FeliCa - Wikipedia
参考: Suica - Wikipedia

🔗CSS/HTML/フロントエンド/テスト/デザイン

🔗 View Transitions APIで進化するCSSアニメーション


つっつきボイス:「動画を見るのが早いと思います↓」「ChromeのView Transitions APIを使うとこういう操作が可能になるのか」「JavaScriptでstartViewTransition()を呼び出している部分がそれのようですね: こうやってシンプルに書けるのはよさそう👍」


同記事より

See the Pen
Radiento - Bento Radio Group Carousel thing
by Adam Argyle (@argyleink)
on CodePen.

参考: Smooth and simple transitions with the View Transitions API - Chrome Developers
参考: Document: startViewTransition() method - Web APIs | MDN

🔗言語/ツール/OS/CPU

🔗 GitHub Copilotでテストを書く


つっつきボイス:「このツイートの言う通り、GitHub Copilotのテストコード生成はマジ賢い🦾とRailsをやっていても思いますね: 最初の時点で読みやすいコードを書いているかとか適切な変数名を使っているかといった点が影響しますけど、そうした部分をちゃんとやっていればキレイに生成してくれる」「ますます"最初のコードが肝心"になってきますね」「型を書かないRubyでここまでキレイなコードを生成するぐらいだから、他の型付き言語だとさらに具合よくやれるかも」

参考: GitHub Copilot の概要 - GitHub Docs


後編は以上です。

バックナンバー(2023年度第3四半期)

週刊Railsウォッチ: Active Storageバリアントの事前変換、Linkヘッダープリロードのオプトアウトほか(20230802前編)

ソースの表記されていない項目は独自ルート(TwitterやはてブやRSSやruby-jp SlackやRedditなど)です。

Ruby Weekly

RubyFlow

160928_1638_XvIP4h


CONTACT

TechRachoでは、パートナーシップをご検討いただける方からの
ご連絡をお待ちしております。ぜひお気軽にご意見・ご相談ください。