Slide 1

Slide 1 text

出張!Railsウォッチ
 in 銀座Rails#24
 森 雅智 / @morimorihoge 2020/08/28 1
 特集:~令和Devise事情~
 
 ~


Slide 2

Slide 2 text

About Me
 ● 森 雅智: @morimorihoge
 ● BPS株式会社でRailsの受託開発チームをやってたり、週1大学非常勤で Web開発を教えてたりします
 ● Ruby/Rails歴は11年くらい。Web開発は17年くらい
 ● 銀座Ralis #10でActiveRecordでVIEWを使おうという話をしました
 About BPS & TechRacho
 ● Web受託開発や電子書籍製品開発をやっている会社です
 ● TechRachoという自社技術Blogを運営しています
 ○ 3年半ほど前から平日毎日更新してます
 ○ https://techracho.bpsinc.jp/ ● お仕事相談、転職相談、TechRachoへのご意見など気軽にどうぞ
 ○ https://www.bpsinc.jp/ 2


Slide 3

Slide 3 text

Railsウォッチとは?
 技術ブログTechRachoで毎週連載しているRails / Ruby界隈を中 心とした雑多な情報を提供する技術雑談マガジン
 3


Slide 4

Slide 4 text

これまでの出張Railsウォッチのピックアップテーマ
 ● Rails6新機能特集
 ○ 銀座Rails#12: 複数DB対応
 ○ 銀座Rails#13: ActionText、Trix
 ○ 銀座Rails#14: ActionMailbox
 ● Railsアプリケーション開発に関する雑多なテーマ
 ○ 銀座Rails#15: production、development、staging環境について
 ○ 銀座Rails#16: 機能開発の設計レビューについて
 ○ 銀座Rails#17: リソース管理スコープについて
 ● 開発一般な話
 ○ 銀座Rails#19: 開発チームの冗長化について
 ○ 銀座Rails#20: Excelと仲良くしよう
 ○ 銀座Rails#21: 標準仕様を読むためのABNF
 ○ 銀座Rails#22: CLIプログラムにOptionParserを使う
 ○ 銀座Rails#23: ActiveRecordのSELECTベンチマーク
 4
 ※過去のスライドは順次TechRachoにて公開しています。「TechRacho 銀座Rails」あた りで検索するとヒットしますので興味のある方はどうぞ


Slide 5

Slide 5 text

~令和Devise事情~
 5


Slide 6

Slide 6 text

Deviseってなに?(知らない人向け)
 ● Railsに組み込むことができる認証Gem
 ○ https://github.com/heartcombo/devise 
 ● Deviseの特徴
 ○ とても古く(2010年)からあり、 継続的にアップデートされ続けている超老舗Gem 
 ○ 認証機能としてDB認証以外にOAuth2、SAML他多数の認証方式と連携することができる(よくある SNSログイン組み込みが簡単にできる) 
 ○ 認証に関連する「よくある」機能がビルトインされている 
 ■ 会員登録(メールアドレスのURLアクセス認証を含む)、パスワード忘れ、アカウントロック、 ロ グイン元IPの記録、etc.
 ● Railsで認証といえばDeviseというレベルで利用されている
 6
 ※Ruby ToolboxのWeb Authenticationカテゴリより 


Slide 7

Slide 7 text

ことの流れ(抜粋)
 ● 国内某大手ブログサービスで投稿者のIPアドレスがHTMLソース内に埋め込まれて いるというセキュリティインシデントが発生
 ● 独自に現状調査した人たちの一部から、IPアドレスが保存されている変数名から恐 らくバックエンドにDeviseを使っているのではないかという憶測が立つ
 ● 恐らくDeviseのUserオブジェクトをそのまま公開したというよくありそうなミスから データが流出したのでは?という憶測が立つ
 ● 本件に関連してか「Deviseはセキュリティ上危険なのでRailsを良く知らない人は使う べきではない」という言説を唱える人が出る
 ● ここまでの流れに対して界隈で話題が盛り上がる(主にTwitterやブログ界隈)
 ● 8/28現在、概ね議論は収束しつつあるように見える
 7
 主な観測範囲がTwitterだったりはてブだったりで偏っている点はご了承下さい


Slide 8

Slide 8 text

誤解を広げる前にいくつかの捕捉事項
 ● 件の某ブログサービスがDeviseを利用しているという確固たるエビデンスは見渡す 限りありませんでした
 ○ 変数名一致の件は単にDeviseの実装を参考にしただけかもしれないし、そもそもRailsですらない可 能性もあるので断定は禁物 
 ● 「恐らくこうしてしまったのではないか」という実装についても、現行のDeviseではイ ンシデントに繋がることはありませんでした
 ○ Devise付属のBLACKLIST_FOR_SERIALIZATIONが阻むはず 
 ● 「Deviseにはセキュリティ上の問題がある」という問題を根拠付きで議論している人 は見当たらなかったので、Deviseを使うこと=危険というわけではありません
 ○ 「危険な実装ができてしまう」のはライブラリの脆弱性ではなく利用する開発者側の問題 
 8
 本発表では今回の問題をダシに、Devise界隈で頻発するこうした議論について整理す ることを試みます


Slide 9

Slide 9 text

あなたとわたしとDevise
 ● Deviseを使ったRailsアプリを触った経験のあるひと?
 ● Deviseを利用する部分の実装に携わった経験のあるひと?
 ● Devise周りの実装を行う上でとても苦労した辛い経験のあるひと?
 ● Deviseになるべく関わりたくないと思っているひと?
 9


Slide 10

Slide 10 text

Deviseは議論を呼ぶ
 ● これほど利用率が高いのに、苦労話が絶えないのはなぜなのか?
 10
 <パンドラの箱を開けてみないかい? 


Slide 11

Slide 11 text

Deviseが敬遠される理由
 ● デフォルト動作のカスタマイズがし辛い
 ● テーブル設計や実装がレガシーでとっつきにくい
 ● Userモデルへの機能の集中が大きく、無節操に拡張されがち
 11


Slide 12

Slide 12 text

デフォルト動作のカスタマイズがし辛い
 ● デフォルトの動作が作りこまれている分、デフォルトで想定しない実装をしようとす ると急に難易度が上がる
 ○ devise_forやdevise_scopeの設定方法と挙動 
 ○ Deviseのメソッドをオーバーライドして挙動を変更するなど、Devise独自の知識やノウハウが多数必 要になってくる
 ● 諸々の参考にする先はDevise Wikiとなるが、how to集のようになっており参照し辛 かったり、そもそも実装が昨今のRails的でないコードも散見される
 ○ https://github.com/heartcombo/devise/wiki 
 ○ そのままコピペすると既存コードによってはまずそうなものもあるので、お手軽さが失われていく 
 12


Slide 13

Slide 13 text

テーブル設計や実装がレガシーでとっつきにくい
 ● 付属の-able系機能はUserモデルにカラムを増やして機能を後付けしていく設計
 ○ -able系の機能に応じて対応するDBカラムを追加すると動作する 
 ○ 実装としてはわかりやすいが、 Userモデルの責務が増えすぎる 
 ○ ※-able系という名前を付けて任意モデルに機能を追加していく実装はRails3くらいの頃にとても流 行りました
 13


Slide 14

Slide 14 text

Userモデルへの機能の集中が大きく、無節操に拡張されがち
 ● Devise公式推奨?ではUserモデルにアプリケーションごとの必要カラムを追加して いく想定となっている
 ○ `current_user.some_column` のような形で認証に関係のないユーザー情報にもアクセスできる 
 ○ 実装としては分かりやすく見えるが、 Userモデルがひたすらfatになっていく問題を孕む
 14


Slide 15

Slide 15 text

Deviseのメリットを再考する
 ● 「広義のログイン認証」機能は一般的なWebサービスにほぼ必須の機能であるにも 関わらず「普通に使えるレベル」として要求される要件が複雑かつ高難度
 ○ 一般的な機能要件
 ■ 会員登録~メール経由での本人確認 
 ■ ログイン・ログアウト 
 ■ パスワード忘れ
 ○ 非機能要件
 ■ 一般的なセキュリティ対策(セキュアなパスワード管理、各種攻撃対策など) 
 ■ 将来のセキュリティアップデート対応 
 ● 認証機能を作るのはサービスの最初期なので、その時点ではサービスがどう育つ か不透明
 ○ ローンチ時期の限られたリソースをサービスの価値に直接繋がらない部分にかけるのは妥当なの か問題
 ○ 追加でSNS認証を追加したいなどの仕様変更要望もありがちだが、前もって備えすぎてもYAGNIに なりがちなので、まずは スピードを重視したいことが多い 
 15
 Deviseを使うことで初期に「よくある認証機能」一式が手に入るメリットは大きい


Slide 16

Slide 16 text

Deviseが辛くなるタイミング
 ● サービスがそこそこ使われだし、拡大フェーズに入った時
 ○ デフォルトの会員登録遷移をカスタマイズ してグロースハックしたい 
 ○ 2段階登録や外部サービスとの繋ぎ込み の要望が出てログイン導線自体が増える 
 ○ その他サービスに合わせた独自機能を連携させたくなってくる 
 ● サービスが成熟・拡大し、大規模な内部設計の見直しが必要になった時
 ○ ログイン認証を外部システムに移行したい 
 ○ フロントエンドのSPA化に伴いAPI化したい(Devise wayでない実装が求められる) 
 ○ Userモデルが太り過ぎたのを再設計したい(大抵辛い) 
 16
 これらのタイミングでは最初にDeviseを組み込んだエンジニアが チームからいなくなっていることも多いぞ!
 それがさらなるhateを生み出していると思うんだなあ
 辛いマン


Slide 17

Slide 17 text

どうすればいいのか?
 ● 既にDeviseを使っている
 ○ なるべくUserモデルのfat化を加速させないように、注意深く設計を行う 
 ○ ViewやAPIレスポンスにUserモデルのインスタンスが渡っている場合、見えてはいけないデータが 漏れていないかテストコードなどでチェック する
 ■ そもそもUserモデルを直接渡さずDecorator / Presentorなどを通すのも良い 
 ● 新しくDeviseの利用を検討している
 ○ なるべくUserモデルの責務が大きくなりすぎないような設計を検討する 
 ○ Devise付属の機能を全て使わないといけないわけではない ので、Deviseのどの機能をそのまま使 い、どの機能は独自で作るかをよく考える(後述するjoker1007さんのサンプルなどは良い参考にな る)
 ■ 特に、会員登録機能やトラッキング機能などは分けておいた方が良さそう 
 ○ はじめてDeviseを使うときは、Devise経験の豊富な人が周りにいたら軽く相談してから使い始める のも良い(Devise公式を愚直にやるとfatになります) 
 ● そもそもRailsで認証(アカウント管理)を扱わない
 ○ 認証が必要なだけなら Auth0やAWS Cognito等の外部サービスを使う手もある 
 ○ が、それはそれで扱いづらくなる点もあるので痛し痒し 
 17


Slide 18

Slide 18 text

例えばこんな感じに責務分割していくなど(仮)
 18


Slide 19

Slide 19 text

これはオススメできない
 ● Rails Tutorialのコードなどを参考に、自前で認証系のコードをフル実装して本番に 投入するのはやめておきましょう
 ○ 認証系の実装に充分な技術的・工数的リソースが投入できるという特殊な場合を除き、大抵辛い未 来が待っている
 ○ 「このサービスはシンプルな認証しかいらないから大丈夫」という予想は大抵覆される運命 にある
 ○ 特にセキュリティ面については、それなりに経験のあるエンジニアでも充分にセキュアな認証コード を書くのは難しいレベルで考慮するものが増えているので、なるべく自作はしない 
 19


Slide 20

Slide 20 text

本件に関連する参考記事など
 ● 認証自作、 Rails 、 Devise
 ○ https://diary.app.ssig33.com/491 
 ○ 盛り上がりの発端となった記事 
 ● Railsで認証機能を自作する?それともDeviseを使う?
 ○ https://sinsoku.hatenablog.com/entry/2020/08/16/190810 
 ○ 銀座Railsでも登壇されている神速さんの記事。とても現実的な内容に思う 
 ● パーフェクトRails著者が解説するdeviseの現代的なユーザー認証のモデル構成に ついて
 ○ https://joker1007.hatenablog.com/entry/2020/08/17/141621 
 ○ Ruby/Rails界隈でおなじみjoker1007さんの記事。2020年にDeviseを使おうと思っているなら一度は 読んで損はない内容 
 ● ちょっとでもセキュリティに自信がないなら、 Firebase Authentication を検討しよう
 ○ https://mizchi.dev/202008172159-firebase-authentication 
 ○ フロントエンド界隈でおなじみmizuchiさんの記事。必要な機能が認証だけならありだよね、という思 い
 20
 他にもよさそうな記事があれば #ginzarails で教えてください :)


Slide 21

Slide 21 text

次回以降もブラッシュアップしていきます
 感想・リクエストなどあればTwitter
 #ginzarails
 @morimorihoge
 @hachi8833
 までお声かけください
 21