XSSとは

XSSクロスサイトスクリプティング(Cross Site Scripting)の略称で、そのまま略すとCSSとなり、Cascading Style Sheetsと誤解を生むため、XSSと呼ばれている。

XSSはWebアプリケーションの脆弱性もしくはそれを利用した攻撃のことをいい、ウェブサイト自体に対してではなく、そのウェブサイトのページを閲覧している利用者に影響する。

image.png 安全なウェブサイトの作り方 - 1.5 クロスサイト・スクリプティング

発生しうる脅威

クロスサイト・スクリプティング攻撃により、発生しうる脅威は次のもの。

  • 本物サイト上に偽のページが表示される

  • ブラウザが保存しているCookieを取得される

    • セッションIDがCookieに格納されていると、更に利用者へのなりすましにつながる
    • Cookie に個人情報等が格納されている場合、その情報が漏えいする
  • 任意のCookieをブラウザに保存させられる

XSSの種類

XSSは主に三つの種類に分類される。

  • 反射型クロスサイトスクリプティング (非持続的)

    サーバは、HTTPリクエストからデータを直接読み込み、読み込んだデータをHTTPレスポンスで返す。反射型XSS攻撃では、脆弱なWebアプリケーションに対して、攻撃者が被害者に危険なコンテンツを送信させる際に発生する。この危険なコンテンツは、被害者に返され Web ブラウザ上で実行される。

    一般的な手段として、次のような手順で実行される。

    1. 悪意あるコンテンツを URL のパラメータに含めて公の場に掲示
    2. 攻撃者は被害者を信じ込ませて悪意あるURLにアクセスさせる
    3. 悪意あるサイトが攻撃者のコンテンツを被害者に返す
    4. 被害者のブラウザ上で攻撃者のコンテンツが実行される
    
  • 格納型クロスサイトスクリプティング (持続的)

    アプリケーションは、危険なデータを何かしらの方法で記憶する(データベース、メッセージフォーラム、訪問者のログ、または他の信頼できるデータストア)。このデータは、その後、このアプリケーションに読み戻され、動的コンテンツの中に含まれる。

    例えば、管理者によるログ参照の際に適切に扱われないログメッセージにXSSを挿入することで、特別な権限を有するユーザになりすまし、権限が必要な操作を実施するなどの悪用方法がある。

  • DOMベースのクロスサイトスクリプティング

    他2つのXSSでは、サーバがWebページに対してXSSを挿入するが、DOMベースのXSSでは、クライアントがXSSをWebページに挿入する。例えば、ユーザが投稿する前にフォーム上で内容確認をするような状況が当てはまる。

    つまり、サーバの提供するスクリプトが、ユーザの提供するデータを処理した後に、そのスクリプトを (動的HTML等の手段により) Web ページに埋め込んで返すと、DOMベースのXSSとなる。

注意すべきページの特徴

次のようなサイトは特に注意が必要。

  • Cookieを利用してログインのセッション管理を行っているサイト
  • ログイン画面、個人情報の入力画面等のフィッシング詐欺ターゲットになりやすいページを持つサイト

より具体的には次のような機能を持つページはXSS脆弱性が生じやすい。

  • 入力内容を確認させる表示画面(会員登録、アンケート等)
  • 誤入力時の再入力を要求する画面で、前の入力内容を表示するとき
  • 検索結果の表示
  • エラー表示
  • コメントの反映(ブログ、掲示板等) 等

対策の種類

クロスサイト・スクリプティング脆弱性への対策は、ウェブアプリケーションの性質に合わせ、次の3つに分類される

  • HTMLテキストの入力を許可しない場合の対策

    検索機能や個人情報の登録等、HTMLタグ等を用いた入力を許可する必要がないもの。多くのアプリケーションはここに該当する。

  • HTMLテキストの入力を許可する場合の対策

    自由度の高い掲示板やブログ等。例えば、利用者が入力文字の色やサイズを指定できる機能等を実装するために、HTMLテキストの入力を許可する掲示板など。

  • 全てのウェブアプリケーションに共通の対策

    上の2つの両者に共通して必要な対策。

HTMLテキストの入力を許可しない場合の対策

根本的解決は次のもの。

  • ウェブページに出力する全ての要素に対して、エスケープ処理を施す

    • ウェブページの表示に影響する特別 な記号文字(<>&等)を、HTML エンティティ(&lt;&gt;&amp;等)に置換する
    • HTML タグを出力する場合は、その属性値を必ずダブルクオート(")で括り、ダブルクオートで括られた属性値に含まれる"を、HTMLエンティティ(&quot;)に置換する
  • URLを出力するときは、http://https://で始まるURLのみを許可する
  • <script>...</script> 要素の内容を動的に生成しない。
  • スタイルシートを任意のサイトから取り込めるようにしない

上記に加えて、保険的に次のような対策もある。(保険的対策は根本を解決できるものではないため、名前の通り保険的な対策として導入する)

  • 入力値の内容チェックを行う

HTMLテキストの入力を許可する場合の対策

根本的解決は次のもの。

  • 入力されたHTMLテキストから構文解析木を作成し、スクリプトを含まない必要な要素のみを抽出する

    構文解析を行い、「ホワイトリスト方式」で許可する要素のみを抽出する。この方法は、複雑なコーディングが要求され、処理に負荷がかかる影響もあるため、十分な検討が必要。

上記に加えて、保険的に次のような対策もある。

  • 入力されたHTMLテキストから、スクリプトに該当する文字列を排除する

全てのウェブアプリケーションに共通の対策

根本的解決は次のもの。

  • HTTPレスポンスヘッダのContent-Typeフィールドに文字コード(charset)を指定する

上記に加えて、保険的に次のような対策もある。

  • Cookie情報の漏えい対策として、発行するCookieにHttpOnly属性を加え、 TRACE メソッドを無効化する
  • クロスサイト・スクリプティング潜在的脆弱性対策として有効なブラウザの機能を 有効にするレスポンスヘッダを返す

参考サイト

Sinatra:erbファイルはrubyコードが書ける

少しずつerbファイルの書き方がわかってきた😅どうやら、<% %>で括った部分がruby コードと判定され、変数については<%= %>で括ってあげると認識されるっぽい。 それ以外の部分についてはhtmlとして扱われる。

例えば、下にerbのコード例を示す。

<% require './myapp.rb' %>
<h2><div><%= @content %></div></h2>

<div class="memo">
  <ul>
    <% get_memo_num.times do |i| %>
      <% memo_info = open_memo_detail(i+1) %>
      <li><a href="/show?id=<%= memo_info[:id] %>"><%= memo_info[:name] %></a></li>
    <% end %>
  </ul>
</div>

<form action="/new" method="get">
  <button type="submit">追加</button>
</form>

上記の内容で、次のWebページを構築できる。

image.png

Sinatra:PRGパターンを実装してみた

Sinatraのサーバ部分はruby、Webページはhtmlというハイブリッド型?🤔

Sinatraの構成にまだ慣れていなくて、『どう書けばいいねん😵‍💫』て感じでしたが、とりあえず手を動かしてみるとだんだん見えてきました😅

自分の感覚的には、『サーバっぽい部分をrubyで処理してあげて、ブラウザ上に表示されるWebページ部分はhtmlで描画する』という印象を受けました。

例えば、GETメソッドの流れを見てみると、次のような流れになっている。

image.png

さらにPOSTメソッドについても見てみた。POSTメソッドはPRGパターンを意識して、一度リダイレクトをクライアントに返して、GETメソッドでコンテンツを表示するようにしてみました😀

image.png

なんとなくsinatraの動きがわかってきたような気がしました😅

PRGパターンとは

PRGは、Post/Redirect/Getの略で、フォーム送信後に表示されるページを再読み込み、共有、ブックマークしても、再度フォームを送信するなどの悪影響がないようにするためのウェブ開発デザインパターンのことらしい。

例えば、herokuのサンプルページ(New Article)が、PRGパターンに従っていない場合、下記のような構成になる。

image.png

上記のようなWebサイトで、POSTリクエストでサーバーに送信された場合に、サーバーのレスポンス結果に対して更新してしまうと、元のPOSTの内容が再送信され、コンテンツが二重登録される。ECサイトとかだと、Web購入が重複する等の望ましくない結果になってしまう。

一部のブラウザでは、POSTリクエストを再発行しようすると、下記のような警告をユーザーに通知してリスクを軽減している。

image.png

上記の課題への対策として、PRGパターンが採用されている。PRGパターンでは、コンテンツを応答する代わりに、サーバーはクライアントを別の場所にリダイレクトするようにPOSTリクエストに応答する。

image.png

上記のように、PRGパターンでは、サーバはPOSTリクエストに対してリダイレクトを返し、クライアントは受け取ったURIにて再度GETリクエストを出して、POSTの結果を取得することになる。これにより、クライアントが結果ページにて更新しても、GETメソッドが送られるだけのため、二重登録されることを防げる。

ただ、PRGパターンは、フォームの重複送信のすべてのシナリオに対応することはできない。例えば、サーバーの遅延が原因で最初の送信が完了する前にクライアントが更新すると、特定のクライアントで重複したPOSTが発生してしまう。

参考

Webを支える技術:リソース設計とは

リソース設計は、クライアントとサーバ間のインタフェース設計、つまりWebサービスやWeb APIの外部設計のことを言う。

設計のポイントは、どのようにリソースを分割し、URIで名前をつけ、相互にリンクを持たせるかという点。その際、WebサービスとWeb APIを分けて考えないということも大切。

リソース設計のアプローチ(読み取り専用)

リソース設計の指針として、『リソース指向アーキテクチャ』があり、このアーキテクチャでは4つの性質を満たす。

項目 説明
アドレス可能性 URIだけでリソースを一意に特定できる。
接続性 リソースをリンクで接続し、1つのアプリケーションを構成する
統一インタフェース HTTPのように決められたメソッド(GET/POST/PUT/DELETE等)でアクセスする。
ステートレス性 状態を持たない通信。現実的にはCookieによるセッション管理が世の中の主流のため、そこまで重要でない。

設計アプローチは、次のステップから構成される。(ステップ4からは、それぞれのリソースに対して実施していく。)

  1. Webサービスで提供するデータを特定する
  2. データをリソースに分ける
  3. リソースにURIで名前をつける
  4. クライアントに提供するリソースの表現を設計する
  5. リンクとフォームを利用してリソース同士を結びつける
  6. イベントの標準的なコースを検討する
  7. エラーについて検討する

Webサービスで提供するデータを特定する

サービスで提供するデータを理解し、特定する

データをリソースに分ける

リソースは、Web上に存在する名前のついた情報であるため、『当該のWebサービスが提供する情報は何か』について考え、リソースを分けていく。

注意としては、『何かを検索する』というのは機能であるため、『検索結果』という情報がリソースになる。

リソースにURIで名前をつける

リソースがとして一意に定まるようなものはURIに組み込む。例えば、郵便番号のようなものは、それだけで一意に定まるため、次のようなURIになる。

http://example.com/1120002

クライアントからの入力を受け取るもの(検索等)は、次のようにクエリパラメータを利用する。

http://example.com/search?q=名古屋市

一部がパラメータとして変動するURIを記述する場合は、パラメータ部分をURI Templateという{}で括った表記が一般的。

http://example.com/search?q={query}

階層構造を持つリソースは/URIを表現する。例えば、市町村であれば次のような表記になる。

http://example.com/{都道府県名}/{市町村名}/{町域名}

クライアントに提供するリソースの表現を設計する

XML表現、軽量フォーマット表現、マルチメディア表現といった表現形式を決定する。1つのリソースが複数の表現形式をサポートしていると使い勝手が良い。

リンクとフォームを利用してリソース同士を結びつける

上記までで設計してきたリソースをリンクで接続する。トップページへのリンクやパンくずリストなどを用意するのが一般的。

接続した結果のリンク関係を図に起こしてあげると、リンク付け漏れなどの問題に気付きやすい。

イベントの標準的なコースを検討する

Webサービス提供者が想定する標準的な利用コースを考える。ユースケース記述のようなものをイメージするとわかりやすい。

エラーについて検討する

『存在しないURIを指定された』、『必須パラメータがない』、『サポート外のメソッドを使用』といった形で、どのような時にどんなステータスコードを返すかを検討しておく。

リソース設計のアプローチ(書き込み可能)

基本的なアプローチは読み取り専用時と同じだが、注意を払う必要がある処理もある。それぞれの処理および対応について、次にまとめる。

注意を払う処理 対応方法
複数リソースの更新 バッチ処理(作成・更新したいリソースを一括で送信)
複数ユーザによる同時書き込み 排他制御(複数のクライアントが同時に1つのリソースを編集して競合が起きないように、1つのクライアントのみが編集するように制御する)
複数の処理手順を必ず実行する トランザクションリソース(複数のリソースにまたがった変更をひとまとまりに扱う

データからリソースにする検討方法

リソース設計のアプローチの『Webサービスで提供するデータを特定する』、『データをリソースに分ける』の部分がかなり苦労する。

その設計方法として次のものがある。

既存設計手法の成果物 導出が得意な部分 導出が苦手な部分
ER図 リソースのリンク関係 ・階層構造
・トップレベルリソース
クラス図 ・リソースのリンク関係
・階層構造
トップレベルリソース
情報アーキテクチャ ・リソースのリンク関係
・階層構造
・トップレベルリソース
特になし

情報アーキテクチャは、リソース指向アーキテクチャと相互に保管関係にあるため、ER図やクラス図のものよりも設計の上で相性が良い。

参考

Webを支える技術:HTTP概要

HTTPメソッド概要

8つのメソッド

メソッド名 役割
GET リソースの取得
POST ・子リソースの作成
・リソースへのデータ追加
・そのほかの処理
PUT ・リソースの更新
・リソースの作成
DELETE リソースの削除
HEAD リソースのヘッダ(メタデータ)の取得
メタデータ:データを説明するデータ
OPTIONS リソースがサポートしているメソッドの取得
TRACE 自分宛にリクエストメッセージを返す試験(ループバック)
CONNECT プロキシ動作のトンネル接続への変更

POSTPUTもリソース作成できるけど、どういう使い分けがある🤔?』と思ったけど、説明がちゃんとありました🤗

明確な正解はないが、設計指針として次の事実があるらしい。

POSTでリソースを作成する場合、クライアントはリソースのURIを指定できません。URIの決定権はサーバ側にある。 逆にPUTでリソースを作成する場合、リソースのURIはクライアントが決定します。

具体的な例だと、TwitterのつぶやきのURIはサーバ側で決定されるのでPOSTを用いて、Wikipediaはクライアントが決定したタイトルがURIになるのでPUTが用いられるのが一般的らしい。

上記の違いから、POSTの場合、作成されたリソースのURIをクライアントはわからないため、リクエストメッセージのレスポンスのLocationヘッダでURIを受け取る。一方、PUTの場合は、クライアントがURIを決定できるため、レスポンスでLocationヘッダが返される必要はない。

べき等性と安全性

HTTPメソッドにはべき等性安全性という性質がある。べき等性は『ある操作を何回行っても結果が同じ』ことを意味し、安全性は『操作対象のリソースの状態を変化させない』ことを意味する。よく使われるメソッドについて、性質をまとめる。

メソッド名 性質
GET、HEAD べき等かつ安全
PUT、DELETE べき等だが安全でない
POST べき等でも安全でもない

例えば、GETはリソースを取得するだけなので『べき等かつ安全』、PUTはリソースに何回発行しても同じ結果(リソースの内容が更新される)になるので、『べき等でないが安全』となる。

注意としては、WebサービスやWeb APIの実装として、上記の性質を守るように設計することが大事。設計を誤るとGETにおいてもリソースの削除をさせることができてしまうため。

ステータスコード

ステータスコードは3桁の数字で、先頭数字により5つに分類される。

コード 分類 説明
1xx 処理中 処理が継続していることを示す。
2xx 成功 リクエストが成功したことを示す。クライアントはリクエストを継続するか、サーバ指示に従いプロトコルをアップデートして再送信する。
3xx リダイレクト ほかのリソースへのリダイレクトを示す。クライアントはこのステータスコードを受け取ったら、レスポンスメッセージのLocationヘッダを見て新しいリソースへ接続する。
※リダイレクト:別のURIにクライアントが自動的に再接続する処理。
4xx クライアントエラー エラー原因がクライアント側にあるエラー。エラーを解消しないと正常結果を受け取れないため、同じリクエストの再送信はできない。
5xx サーバエラー エラー原因がサーバ側にあるエラー。サーバ側の原因が解消されれば、同一リクエストを再送信して正常な結果を得られる可能性がある。

ここでのポイントしては、リダイレクトもサーバ側が実装しておかないとリンク切れを起こすという点。WebサービスやWeb APIでエラーが起きた時に、どのエラーステータスコードを返すかは、重要な設計の検討事項の一つ。

HTTPでの認証

あるリソースにアクセス制御がかかっている場合、ステータスコード401:Unauthorized(このリソースのアクセスには適切な認証が必要)WWW-Authenticateヘッダを利用することで、クライアントにリソースへのアクセスに必要な認証情報を通知することができる。

HTTP認証方式には、次のものがある。

方式名 説明
Basic認証 ユーザ名とパスワードをBase64エンコードした文字列を、Authorizationヘッダに入れて送信する。Base64エンコーディングは簡単にデコードできるので注意。注意としては、メッセージ自体は平文のため、セキュリティ的にはHTTPS対応を利用する方が良い。
Digest認証 あるメッセージに対してハッシュ関数を適用した結果のハッシュ値を用いて送信する。サーバからのチャレンジに対して、クライアントはダイジェストを生成し、nonce:nubmber used onceqop:quality of protectionを連結したメッセージをサーバに送信する。注意としては、メッセージ自体は平文のため、セキュリティ的にはHTTPS対応を利用する方が良い。
WSSE HTTP1.1の標準外の認証方式。AtomPubなどのWebAPIで使われる。

キャッシュ用ヘッダ

キャッシュは、サーバから取得したリソースをクライアントのローカルストレージに蓄積し、再利用する手法のこと。蓄積されたキャッシュは、そのキャッシュが有効な間、クライアントが再度当該リソースにアクセスしようとするときに再利用される。

キャッシュ用のヘッダとして次のものがある。

ヘッダ名 説明
Pragma キャッシュを抑制する(リソースのキャッシュを制限する)
Expires キャッシュの有効期限を設定する
Cache-Control 細かくキャッシュを制御する

使い分けの方針は次の通り。

  • キャッシュさせない時:PragmaCache-Controlno-cacheを同時に設定
  • キャッシュの有効期限が明確に決まっている時:Expiresを指定する
  • キャッシュの有効期限を相対的に指定したい時:Cache-Controlmax-ageの相対時間を指定する

参考

個人的には下記の本もわかりやすいと思っています😅

アジャイル開発のやり方

アジャイルサムライを読んでみたので、大事だなと思った内容をまとめる。

大雑把にいうと『アジャイル開発のやり方』を具体的に学べる。いくつか読んだアジャイル本(SCRUM BOOT CAMP THE BOOK, いちばんやさしいアジャイル開発の教本)の中で、一番具体的な進め方を詳細に書いている本だと感じた。

プロジェクトがダメになる理由

基本的に、関係者全員でプロジェクトについて話し合う前にプロジェクトが始まってしまうことが問題。それにより、認識違いなどを引き起こす。

よって、そうならないために次のことが大事。

やること 理由
ゴールやビジョン、プロジェクトの状況、背景についてチームでよく話し合う チームが状況に応じて適切な判断を下せるようにしたい
ステークホルダーに情報を提供する ステークホルダーはプロジェクトを続けるかの判断材料が必要

これを実現するためには、色々と関係者で議論する必要がある。その際に使える手法に、インセプションデッキがある。これは、10の手強い質問と課題に答えるというもの。

インセプションデッキ

インセプションデッキ概要

インセプションデッキは次の10個からなり、前半5つはプロジェクトの『WHY』を把握し、後半5つで『How』を考える。

我々はなぜここにいるのか?

下記を明確にする。

  • 何のためにチームを組むのか?
  • 顧客は誰か?
  • プロジェクトが始まった理由は?

エレベーターピッチ

30秒以内に2センテンスでプロジェクトをアピールするとしたら、何を伝えるべきかを考える。 これを行うと次の恩恵を得られる。

  • 明確になる

    プロダクトが具体的に何で、誰のものかがはっきりする

  • チーム意識を顧客に向けさせる

    プロダクトの強み、顧客が対価を支払う理由がはっきりする

  • 核心を捉える

    本当に重要なことが何かが明らかになり、優先順位をつけるときに役立つ

エレベーターピッチのテンプレート

  • [潜在的なニーズを満たしたり、抱えている課題を解決したり]したい
  • [対象顧客]向けの
  • [プロダクト名]というプロダクトは、
  • [プロダクトのカテゴリー]である。
  • これは[重要な利点、対価に見合う説得力のある理由]ができ、
  • [代替手段の最右翼]とは違って、
  • [差別化の決定的な特徴]が備わっている

ちなみに、エレベーターピッチの由来は、『エレベーターに乗っている短い時間で投資家にプロダクトをPRし、資金援助を獲得する』というところから来ており、ごく短い時間でアイデアの本質を伝えるという意味になる。

パッケージデザイン

雑誌のページに、プロダクトやサービスの広告が載るとしたら、どんな内容が良いか?また、その広告を見た人は、プロダクトは買いたくなるのかを考える。

次ようなステップを踏むと良い。

  1. プロダクトの効能をブレインストーミングする
  2. キャッチコピーを決める
  3. パッケージをデザインする

やらないことリスト

プロジェクトで実現したいことが明確であるのと同じくらいに、やらなくていいことを一覧化する。それにより、プロジェクトの何がスコープ内で、何がスコープ外なのかが一目瞭然になる。

image.png

「ご近所さん」を探せ

「プロジェクト関係者」を広く集めて、繋がりを作る。チーム全員でブレインストーミングを行い、やりとりが必要な相手を洗い出す。理由は、後々面倒になることを避けるため。

解決案を描く

チーム全員の認識が揃っていることを確認するために、概要レベルのアーキテクチャ設計図を描く。

ここでやることは次の3つ。

  1. どんな風にシステムを構築しようとしているかを図で伝える
  2. どこにリスクがあるかを明確にする
  3. みんながその解決策に同意していることを確認する

チームの開発者が集まって、今回のプロジェクトではどんな風に作るかを相談する。オープンソースフレームワークで使いたいものがあれば、この時点で採用できるかを検討しておく。

夜も眠れない問題

プロジェクトで起きうる問題、心配事を話し合う。最悪の事態を避けられる、被害を最小限に食い止められる方法があるか?

ここでもチームでブレインストーミングを行い、プロジェクトで起こりそうなあらゆるリスクを洗い出す。例えば、インセプションデッキ中に感じた『これはちょっとおかしいんじゃないか』というような違和感など。

リスクを先に洗い出しておく利点は次の通り。

  • プロジェクトの課題を早い段階で明らかにできる
  • 「いや、その理屈はおかしい」を表明するチャンス
  • 単純に気持ちがスッキリする(不安感情を共有することで、チームの結束力も高まる。)

期間を見極める

どれくらいの期間が必要なプロジェクトなのか?

正確に期日を見積もるのは、やっぱり難しい。選択肢として次の2つがある。

  • 期日を軸にして、そこに収まるようにフィーチャーを調整していく

    image.png

  • 中核をなすフィーチャーを届けることにはコミットメントするが、期日については幅を持たせる

    image.png

何を諦めるのか

プロジェクトで操作可能な要素(スコープ、予算、時間、品質)で譲れないもの、譲ることもやむないものを決める。

どんなプロジェクトでも、スコープ、予算、時間、品質は固く結びついており、全てを優先するということはできない。よって、プロジェクトを進める上で何を優先させるかをはっきりさせておく。

そこで使えるのが、トレードオフ・スライダーというツールがある。下記のように、顧客と一緒に何を優先させるかを、あらかじめ合意をとっておく。

image.png

何がどれだけ必要か

期間、コスト、どんなチームなら達成できるかを話す。

ステークホルダーからすると、結局のところ次の回答が欲しい。

  • いつ完了するか?
  • いくら掛かるのか?

ただ、期日や開発チームの仕事のスピード、金額などの様々な数値について、現時点では100%のコミットメントはできない(結局のところ、当てずっぽうなので)。よって、インセプションデッキの内容で全体のプロジェクトの規模などを見せた上で、大体このくらいになりそうということを提示する。

ユーザーストーリー

ウォーターフォール型などでは、要求を捉える手段として要件定義書や仕様書を作るが、結局のところ、そうした文書を作ったところで、文書での伝達には限界がある(誤解を生むし、重厚なものは読んでくれなかったり)。つまり、ものすごい時間とエネルギーを文書化にかけている。(『何を成し遂げたいのか?』ということではなく、『何を文書に書くか』に注力してしまっている)

ユーザーストーリーとは

従来のやり方での課題から、アジャイルでは『文書に頼りすぎてはいけない』ということを教訓とし、次のような何かが必要だとしている。

  • お客さんが欲しいと思っていることの本質を捉えるようにしたもの
  • 計画を立てるときに何のためだったかを理解できるくらいには詳細なもの

上記のようなことを満たすために考えられたのがユーザーストーリー。ユーザーストーリーは、顧客がソフトウェアで実現したいと思っているフィーチャーを簡潔に記述したもの。

ユーザーストーリーのポイント

ユーザーストーリーは、インデックスカードを使って、フィーチャーの本質を捉えるキーワードを書き出す。よって、ありとあらゆる要求を聞き出すことが目的ではない。

なぜ本質以外の要求を聞き出さないかというと、そういった事柄は後になっていらなくなることが多いため、本当に必要になるという時までは、放っておく。そうすることで無駄なことにエネルギーを割かなくて良くなる。

また、よく書けているユーザストーリーは次の特徴を持つ。

  • 顧客にとって何かしら価値が書かれている
  • エンドツーエンドになっている(ケーキを切った時のように、それだけでお客さんにとって価値がある)
  • 独立している
  • 交渉の余地がある
  • テストできる
  • 小さい、見積もれる

少し細く書きたい時のテンプレート

ユーザーストーリーは、適切な言葉で簡潔に書かれていれば、チーム全員が思い出せるのでそれでOK。例えば、『ログインする』とか。

ただ、もう少しストーリーの前提となる状況をはっきりしたいときには、次のようなテンプレートが使える。

<ユーザの種類>として
<達成したいゴール>をしたい
なぜなら<理由>だからだ

上記のように書くことで、『誰が・何を・なぜ』ということを明らかにできる。ただ、ユーザーストーリーの記述としては、少し長くなるので、ユーザストーリーを分析するという時などに使ってみるのも良い。

ストーリー収集ワークショップを開催する

アジャイル開発では、プロジェクト計画時に顧客が求めるフィーチャーリストが必要。そのフィーチャーリストを作るための作戦として、ストーリー収集ワークショップがある。このワークショップでは、開発チームと顧客が一緒になって、開発対象のユーザーストーリーを書く。

ワークショップのステップは次のようなものがある。

  1. 大きくて見通しの良い部屋を用意
  2. 図をたくさん書く(※荒い粒度にとどめる)

    次のような図が使える。

    目的 図の名称
    ユーザを理解する ・ペルソナ
    システムが動作するのに必要な把握する フローチャート
    ・シナリオ
    仕事の構造を整理する ・システム概要図
    ・プロセスフロー
    実際にどんな感じかをイメージできる ・コンセプトデザイン
    ・絵コンテ
    ・ペーバープロトタイプ
    違った観点の何か ・独自に考えた何か
  3. ユーザーストーリーをたくさん書く(エンドツーエンドの機能にする

  4. その他もろもろをブレインストーミングする
  5. リストを書き上げる

見積もり技法

端的に『概算見積もりなんて当てずっぽう』であるのは頭に置いておく。その通りだと思う。

そうはいっても、プロジェクトの予算や成果を期待できるかの見通しを立てないといけない。そこでアジャイルでは、次を踏まえて計画を立てる。

  • ストーリーそれぞれを互いに相対的なサイズで見積もる
  • ポイントを基にして進捗を追跡する

相対サイズで見積もる

ポイントで見積もる

アジャイルでは、見積もりの単位として『ポイント』を採用している。時間にしてしまうと、見積もり時の再調整が多くなり、いつまでも終わらなくなってしまうからだ。使用するポイントの値は、ストーリー間の違いを明確にするために、フィボナッチ数列(とはいっても、1,3,5,8くらいで収まるように)のようなものが好ましい。

見積もり技法①:三角測量

代表的なストーリーをいくつか基準として選出し、残りのストーリーを基準となるストーリーとの相対サイズで見積もる。

基準となるストーリーを選出する観点は次のもの。

  • 論理的なグループ分けができそうなものがあるか
  • エンドツーエンドになっているストーリーはあるか
  • プロジェクトを象徴するような代表的なストーリーはどれか

見積もり技法②:プランニングポーカー

各ストーリーに対して、開発チームのメンバーそれぞれで当該ストーリーのポイントを見積もる。開発チーム全員の考えが見える化され、その段階でチームで話し合えることで、より適切に見積もれるようになる。

アジャイルな計画づくり(初回の計画作り)

初回の計画作りは次のステップからなる。

  1. マスターストーリーリストを作り、リリース(意味のある単位でストーリをまとめたもの)を定義する

    image.png

  2. プロジェクト規模を見極める

    image.png

  3. 優先順位をつける

    image.png

  4. チームのベロシティを見積もる

    image.png

  5. 期日を仮決めする

    期日固定もしくはフィーチャー固定にするかの戦略を立てる

上記の方法で、大体計画を作ることができ、スマートに運用するためには、計画の進捗状況を効率よく確認できた方が良い。その方法にバーンダウンチャート(顧客のストーリーをどれくらいの速度で焼き尽くせるか)がある。バーンダウンチャートでは、次の項目が可視化される。

  • どれだけ仕事を完了させたか
  • どれだけ仕事が残っているか
  • チームのベロシティ
  • いつ頃全てを完了させられそうか

具体的には、下記のような感じ。

image.png

他にも、バーンアップチャートや、バーンアップチャートとバーンダウンチャートを組み合わせたようなものもある。

イテレーションを運営する

イテレーションでは、価値ある成果を毎回アウトプットする必要がある。そのやり方は、次のようにステップをこなす。

  1. 分析と設計:作業の段取りをする

    image.png

    今から1ヶ月こと先のことなんてわからないので、ユーザーストーリーを実装するタイミングが近づいてきてから着手する。具体的な分析のタイミングは、イテレーション中に次のイテレーション

    『ストーリーを分析して、具体的に何をアウトプットするの?』については、システムの動作や必要な手順をシンプルに表現したい場合は、フローチャートなどが使える。ストーリーごとにどんな示し方がいいかを決めて分析する。

    分析が終わったら、テスト条件(このストーリーが完成したことを確認できそうなこと)を書いていく。

  2. 開発:実際に作業する

    分析したストーリーからリリース可能なソフトウェアを実装する。ここでやることは次のもの。

    1. 自動化されたテストを書く
    2. 設計を継続的に発展させ、改善し続ける
    3. ちゃんと動くソフトウェアであり続けるために、継続的にコードをインテグレーションする
    4. 顧客がシステムについて語る言葉に合わせてコードを書く

    また、具体的なストーリー実装に入る前に、イテレーションゼロ(開発準備期間)期間を設け、次のことを済ませておく。

  3. テスト:作業結果の確認をする

    イテレーションのたびにテストは実施する。もちろんリリース前の受け入れテストも必ず実施する。理由は、顧客が本気になってテストを確認するのは、最終的な受け入れテストのスケジュールが近づいてきた時のため。

大ボリュームになったが、アジャイルサムライでとても参考になる部分を自分なりにまとめてみた結果でした。上記のことを意識してアジャイル開発をやってみます!

参考