しばやん雑記

Azure とメイドさんが大好きなフリーランスのプログラマーのブログ

Sitecore と ASP.NET MVC 間でデバイスクッキーを連携させてみた

これは Sitecore Advent Calendar 2013 - Adventar の 12 日目の記事です。

以前に Sitecore と ASP.NET MVC のハイブリッドなサービスの開発をお手伝いした時に、どうしても Sitecore のデバイスクッキーを ASP.NET MVC と共有化させる必要がありました。

デバイスクッキーと言うのは、スマートフォンから見た時に PC 表示への切り替えを行う時に使われてます。はてなブログでもフッターから PC 版への切り替えが出来るようになっていますよね。

f:id:shiba-yan:20131210001910p:plain

ASP.NET MVC では Display Mode という機能が用意されているのでこれを使えば簡単に実装出来ます。ここでは詳細を説明しないので、チャックさんのわかりやすい記事を参照してください。Developer Preview の記事ですが、基本的には変わってません。

ASP.NET MVC 4 : モバイル デバイスの検出とビューの切り替え機能 (1) - THE TRUTH IS OUT THERE - Site Home - MSDN Blogs

本題に戻って、今回は Sitecore とデバイスクッキーを共有させるために、デフォルトの BrowserOverrideStore を継承した SitecoreBrowserOverrideStore を作成しました。

shibayan/SitecoreMvcDisplayMode · GitHub

にてフルセットのコードを公開しておきましたが、一部分だけ実装を持ってきました。

public class SitecoreBrowserOverrideStore : BrowserOverrideStore
{
    private static readonly string _defaultGuid = ConfigurationManager.AppSettings["Sitecore.Device.DefaultGuid"];
    private static readonly string _appleGuid = ConfigurationManager.AppSettings["Sitecore.Device.AppleGuid"];
    private static readonly string _androidGuid = ConfigurationManager.AppSettings["Sitecore.Device.AndroidGuid"];
    private static readonly string _desktopGuid = ConfigurationManager.AppSettings["Sitecore.Device.DesktopGuid"];
    private static readonly string _mobileGuid = ConfigurationManager.AppSettings["Sitecore.Device.MobileGuid"];

    private const string AppleUserAgent = "Mozilla/5.0 (iPhone; CPU iPhone OS 6_0 like Mac OS X) AppleWebKit/536.26 (KHTML, like Gecko) Version/6.0 Mobile/10A403 Safari/8536.25";
    private const string AndroidUserAgent = "Mozilla/5.0 (Linux; U; Android 4.0.1; ja-jp; Galaxy Nexus Build/ITL41D) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30";
    private const string DesktopUserAgent = "Mozilla/4.0 (compatible; MSIE 6.1; Windows XP)";
    private const string MobileUserAgent = "Mozilla/4.0 (compatible; MSIE 6.0; Windows CE; IEMobile 8.12; MSIEMobile 6.0)";

    private static readonly string _cookieName = ConfigurationManager.AppSettings["Sitecore.Device.CookieName"];

    public override string GetOverriddenUserAgent(HttpContextBase httpContext)
    {
        var guid = GetGuidFromCookie(httpContext);

        if (guid == _appleGuid)
        {
            return AppleUserAgent;
        }
        if (guid == _androidGuid)
        {
            return AndroidUserAgent;
        }
        if (guid == _mobileGuid)
        {
            return MobileUserAgent;
        }
        if (guid == _desktopGuid)
        {
            return DesktopUserAgent;
        }

        return null;
    }

    public override void SetOverriddenUserAgent(HttpContextBase httpContext, string userAgent)
    {
        var guid = GetGuidFromUserAgent(userAgent);

        var browserOverrideCookie = new HttpCookie(_cookieName, guid);

        if (userAgent == null)
        {
            browserOverrideCookie.Expires = DateTime.Now.AddDays(-1);
        }

        httpContext.Response.Cookies.Remove(_cookieName);
        httpContext.Response.Cookies.Add(browserOverrideCookie);
    }

    private static string GetGuidFromCookie(HttpContextBase httpContext)
    {
        // 長いので省略
    }

    private static string GetGuidFromUserAgent(string userAgent)
    {
        // 長いので省略
    }
}

仕組みとしては Sitecore が吐き出すクッキーの値*1をそれぞれのデバイス固有の User-Agent にマッピングしているだけです。

そしてクッキー名とアイテム ID は Web.config にて設定する必要がありますので、以下のような設定を appSettings 内に追加してください。

<appSettings>
  <!--  Sitecore とのクッキー連携 -->
  <add key="Sitecore.Device.CookieName" value="SC_DEVICE_COOKIE" />
  <add key="Sitecore.Device.DefaultGuid" value="{A9273D73-5089-4648-B809-696B6A18BB97}" />
  <add key="Sitecore.Device.AppleGuid" value="{195C1762-B4D7-4921-801C-79BB20E48CAE}" />
  <add key="Sitecore.Device.AndroidGuid" value="{73A0FEAD-4770-479E-BDDF-5910F167597D}" />
  <add key="Sitecore.Device.DesktopGuid" value="{66734A1A-ACD3-4E52-B134-07C59CFA21EE}" />
  <add key="Sitecore.Device.MobileGuid" value="{EB059EAB-A48A-4BDA-ADF7-6CF168F2299F}" />
</appSettings>

Sitecore の管理画面からアイテム ID をコピーして、適切に書き換える必要があります。

そして最後の仕上げとして、作成した SitecoreBrowserOverrideStore を使うように設定を行います。これを忘れると当然ながら動きません。

// ストアを Sitecore 用のものに切り替える
BrowserOverrideStores.Current = new SitecoreBrowserOverrideStore();

基本的には Global.asax の Application_Start 内で行えば問題ないです。これで Sitecore と ASP.NET MVC でデバイスクッキーの共有が出来るようになりました。めでたしめでたし。

当然ながらクッキーを使っているので、Sitecore と ASP.NET MVC が同じクッキーを読めるような環境*2じゃないと動作しないです。

ちなみに、自分は Sitecore のライセンスとか持ってないです。念力デバッグで記事が書けました!!(

*1:アイテム ID と言うらしい

*2:具体的には同じドメイン上に Sitecore と ASP.NET MVC を動かす