使ってみよう! Windows Live SDK/API

第17回 Windows Live Application Based Storage API(2)

この記事を読むのに必要な時間:およそ 14 分

続いて今回の本題とは関係ないところを実装してしまいましょう。このWebサイトへユーザーが初めてアクセスした際,まだユーザーデータへのアクセスはできません。最初に承認要求ページへのリンクを表示します。また,承認要求ページから応答があった場合,リソースのアクセスに必要になる承認トークンのdeltとlidパラメータをCookieに保存し,Cookieにデータがある場合は承認要求ページへのリンクを表示しません。

Default.aspx.vbにページの初期動作を次のように記述します。deltパラメータはこのアプリケーションの他の場所でも使用することになるのでString型の変数DelegationTokeに格納しています。コード中にあるParseメソッドやDecryptTokeメソッドについては本連載第14回15回にて作成したメソッドです。

Protected DelegateionToken As String = ""
Protected Sub Page_Init(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Init
    If Request.Cookies("delt") IsNot Nothing AndAlso Request.Cookies("delt").Value <> "" Then
        ' Cookie に委任トークンが格納されている場合
        Me.DelegateionToken = Request.Cookies("delt").Value

    ElseIf Request.Form("ConsentToken") <> "" Then
        ' POSTデータに承認トークンが格納されている場合

        ' 承認トークンから各パラメータ取得
        Dim consentToken As String = Request.Form("ConsentToken")
        Dim pairs As Specialized.NameValueCollection = Parse(HttpUtility.UrlDecode(consentToken))

        ' 暗号化された承認トークンの場合、復号化
        If pairs("eact") <> "" Then
            pairs = Parse(HttpUtility.UrlDecode(DecryptToken(pairs("eact"), "*** Secret key ***")))
        End If

        ' delt(委任トークン)とlidパラメータ値を Cookie に保存
        Dim expires As DateTime = New DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc)
        expires = expires.AddSeconds(CUInt(pairs("exp"))).ToLocalTime()

        If pairs("delt") <> "" Then
            Response.Cookies("delt").Value = pairs("delt")
            Response.Cookies("delt").Expires = expires
            Response.Cookies("lid").Value = pairs("lid")
            Response.Cookies("lid").Expires = expires
        End If

        Me.DelegateionToken = Request.Cookies("delt").Value
    Else
        ' 上記以外の場合、承認要求ページへリンクを表示
        Dim ru As String = HttpUtility.UrlEncode("http://***/")
        Dim pl As String = HttpUtility.UrlEncode("http://***/policy.html")
        Dim ps As String = "ApplicationStorage.ReadWrite"
        Dim mkt As String = "ja-JP"
        ConsentHyperLink.NavigateUrl = String.Format("https://consent.live.com/Delegation.aspx?ru={0}&ps={1}&pl={2}&mkt={3}", ru, ps, pl, mkt)
        ConsentHyperLink.Visible = True
        ResoucePanel.Visible = False
    End If
End Sub

リソースへのアクセスの基本

さて,Application Based Storage APIを利用してこれからユーザーデータにアクセスすることになりますが,その方法については前回にも書いたように次に示す手順になります。

  1. まず,Windows Live委任認証により承認トークンを取得します。

  2. 承認トークンのユーザーデータの場所を表すlidパラメータを使用した以下の書式のURLへHTTPによりアクセスします。

    https://cumulus.services.live.com/@C@[LID]/AtomApplicationStorage[/リソースへのパス]
    

    ※[LID]にはlidパラメータ,[/リソースへのパス]にはリソースへのパスを指定します。

  3. 上記アドレスへアクセスするときに認証用のヘッダを追加します。このときに必要になるのが承認トークンのdeltパラメータ(委任トークン)です。HTTPのヘッダは次のようになります。

    [Method] /AtomApplicationStorage[/リソースへのパス] HTTP/1.1
    Host: cumulus.services.live.com
    User-Agent: [Name of User Agent]
    Authorization: DelegatedToken dt="[委任トークン]"
    

Authorizationヘッダに「DelegatedToken dt="[委任トークン]"」という書式で指定します。Application Based Storage APIを利用したすべてのリソースアクセスにおいてこのヘッダ情報を付ける必要があります。[Method]にはGETやPOSTといったHTTPメソッド名が入ります。

これをVB.NETのコードで表すと次のようになります。Authorizationヘッダを追加したHttpWebRequestクラスを返すメソッドとしてあります。DelegateionTokenは先ほどのコードで作成した変数です。

Protected Function CreatedNewRequest(ByVal path As String, ByVal method As String) As HttpWebRequest
    Dim request As HttpWebRequest = DirectCast(WebRequest.Create(path), HttpWebRequest)
    request.Method = method
    request.Headers(HttpRequestHeader.Authorization) = String.Format("DelegatedToken dt=""{0}""", Me.DelegateionToken)
    Return request
End Function

次からこのメソッドを使用してリソースへアクセスします。

フォルダ・ファイル情報一覧の取得

フォルダやファイル情報の一覧を取得するにはGETメソッドを使います。アドレスのリソースパスには「/RootFolders」「/Items」などのコレクションを表すパスを指定します。そうすると次のようなAtomプロトコルによるFeed形式のXMLが返ってきます。

<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" 
      xmlns:AS="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata" 
      xmlns:AppStorage="http://dev.live.com/AppStorage" 
      xmlns:Live="LiveAtomBase:">
    ...
    <entry AS:type="Folder">
        ...
    </entry>
    <entry AS:type="Photo">
        ...
    </entry>
    <entry AS:type="Document">
        ...
    </entry>
</feed>

<feed>要素内には指定したコレクション内にあるフォルダやファイルの数だけ<entry>要素が含まれています。

以下に<entry>要素を示します。<entry>要素にはAS:type属性があり,Folder・Photo・Documentのいずれかの値になっています。これによりアイテムの種類が判別できます。この属性以外にも<category>のtermやlabel属性も使用できそうです。またアイテムの名前は<title>要素にてわかります。

<entry AS:type="Folder">
    <category scheme="http://dev.live.com/AppStorage/scheme" term="Folder" label="Folder" />
    <id>https://cumulus.services.live.com/@C@[LID]/AtomApplicationStorage/RootFolders(136)/Items('150F')</id>
    ...
    <title>Sample</title>
    ...
    <link href="https://cumulus.services.live.com/@C@[LID]/AtomApplicationStorage/RootFolders(136)/Items('150F')/Items" rel="related" type="application/atom+xml;type=feed" title="Items" />
    ...
</entry>

<id>要素は,<entry>要素が示すアイテム自身へのリソースパスになっています。また,そのアイテムが持つコレクションへのパスはrel属性が"related"となっている<link>要素のhref属性をみることで取得できます。

以下のコードはアイテムの種類がPhotoの場合の<entry>要素内の一部です。画像や文書のアイテムにもrel=⁠related⁠の<link>要素がありパスが設定されています。画像の場合は「PhotoStreams⁠⁠,文書の場合は「DocumentStreams」というコレクションを表すパスになっています。画像や文書といったファイルとなるアイテムは階層の終端のように思いますが,ひとつのファイルの中にも複数のオブジェクトを持つもの,たとえばサムネイル画像や要約文書などを個別に指定するために用意されているものと思われます。

<link href="https://cumulus.services.live.com/@C@[LID]/AtomApplicationStorage/RootFolders(136)/Items('173P')" rel="edit" type="application/atom+xml;type=entry" title="Photo" />
        <content type="image/jpeg" src="https://cumulus.services.live.com/@C@[LID]/AtomApplicationStorage/RootFolders(136)/Items('173P')/$value" length="2857" />
        <link href="https://cumulus.services.live.com/@C@[LID]/AtomApplicationStorage/RootFolders(136)/Items('173P')/$value" rel="edit-media" type="image/jpeg" title="PhotoStream" />
        <link href="https://cumulus.services.live.com/@C@[LID]/AtomApplicationStorage/RootFolders(136)/Items('173P')/PhotoStreams" rel="related" type="application/atom+xml;type=feed" title="PhotoStreams" />

画像と文書のアイテムの場合,rel="edit-media"の<link>要素がありアイテム自身のバイナリデータを表すリソースへのパスが取得できます。その場合のパスの末尾は「$value」です。<content>要素にも同様の記述があります。

著者プロフィール

松江祐輔(まつえゆうすけ)

日本システムウエア株式会社 勤務。現在,ハードウェア設計・検証業務を担当。大学生・大学院生時代はベンチャー企業 有限会社ミレニアムシステムズにプログラマーとして従事。趣味はプログラミング。好きな言語はVisual Basic。Microsoft MVP for Windows Live Platform(Jul 2010 - Jun 2011),Windows Live(Jul 2011 - Jun 2013)。

URL:http://katamari.jp