酢ろぐ!

カレーが嫌いなスマートフォンアプリプログラマのブログ。

Windows PhoneでWebBrowserコントロールを使って自動ログイン機能を実装する

前回、WebBrowserコントロールでUser Agentの偽装が可能であることを紹介致しました。WinFormやWPFのWebBrowserコントロールと比較すると機能が少ないためか余り活用されていない様に感じます。WebBrowserコントロールの可能性をもう少し追ってみましょう。

ログイン用パラメータを指定しIE Mobileを起動するという器用なことがWebBrowserTaskでは出来ませんので、WebAPIが提供されていないウェブサービスの場合、アプリ上からログインさせたいという要望が上がってくるかと思います。

WebBrowserコントロールでは、WebBrowser.InvokeScript メソッド (String, Object[]) (System.Windows.Controls)を使って任意のJavaScrptコードを実行することが出来ます。これを利用して、フォームのユーザー名とパスワードを入力してフォームを送信してみましょう。

どのサービスのログインフォームでも良かったのですが、前回Windows Phone 7に対応する気のないのが判明した「Yahoo!Japan」をターゲットにして試してみましょう。

JavaScrptを実行するためにIsScriptEnabledを有効にする

WebBrowserコントロールは、IsScriptEnabledプロパティに"True"に設定することで、SilverlightアプリケーションからJavaScriptを実行することが出来ます。

XAMLで指定する場合
<phone:WebBrowser Name="webBrowser1" Margin="0,0,0,80" IsScriptEnabled="True" />
コード上で指定する場合

コンストラクタかOnNavigatedTo(NavigationEventArgs)メソッドにてIsScriptEnabledプロパティに"True"を設定しても良いかもしれません。

webBrowser1.IsScriptEnabled = true;

以上で、WebBrowserコントロールの側の準備は完了です。

Yahoo!Japanへのボタン1つでログインする

Yahoo!のログインページは下記のURLです。

https://login.yahoo.co.jp/config/login?.src=www&.done=http://www.yahoo.co.jp

オーバーライドしたOnNavigatedToメソッドで、先ほどのログインURLへ遷移させます。

using System;
using System.Diagnostics;
using System.Windows;
using Microsoft.Phone.Controls;

namespace WebBrowserYahooLoginTest {
    public partial class MainPage : PhoneApplicationPage {

        readonly string url = "https://login.yahoo.co.jp/config/login?.src=www&.done=http://www.yahoo.co.jp";
        readonly string username = "your_id";
        readonly string password = "your_password";
        
        public MainPage() {
            InitializeComponent();
        }

        protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e) {
            // ログインページへ遷移する
            webBrowser1.Navigate(new Uri(url));
        }

        private void button_Click(object sender, RoutedEventArgs e) {
            // ユーザーネームを入力
            var parm1 = string.Format("document.getElementById('username').value = '{0}'", username);
            var ret1 = (string)webBrowser1.InvokeScript("eval", parm1);
            Debug.Assert(ret1 == username);

            // パスワードを入力
            var parm2 = string.Format("document.getElementById('passwd').value = '{0}'", password);
            var ret2 = (string)webBrowser1.InvokeScript("eval", parm2);
            Debug.Assert(ret2 == password);

            // ログイン情報を送信
            webBrowser1.InvokeScript("eval", "document.forms['login_form'].submit();");
        }
    }
}

アプリが起動するとYahoo!Japanのログインページが表示されます。

画面下部にあるLoginボタンが押されるとbutton_Clickメソッドが実行されます。このメソッドではWebBrowser.InvokeScriptメソッドを通して、以下の処理を実行します。

  • 「username」というIDのテキストボックスに「your_id」を設定
  • 「passwd」というIDのパスワードボックスに「your_password」を設定
  • 「login_form」というIDのフォームの情報を送信

JavaScriptコードに置き換えてみました*1

document.getElementById('username').value = 'your_id';
document.getElementById('passwd').value = 'your_password';
document.forms['login_form'].submit();

ユーザーIDとパスワードの入力とフォームの送信が正しく実行されれば、下図のようにログインに成功します。

htmlの構造が変われば当然ログイン時に送信するコードを変更する必要があります。もし他のサービスへのログインが成功したらトラックバックやTwitterで@をください。情報を共有していきましょう。

*1:僕はあまりJavaScriptが得意でないので問題があれば指摘して欲しいです