2015年2月14日土曜日

Firebaseで認証付きアプリを作るには

Firebaseはバックエンドサービスです。BaaS(Backend as a Service)と言われますが、Firebaseのサイトには直接BaaSという言葉はなさそうです。
一言で言うと、ドキュメント型データベースとそのライブラリからなるシステムです。ドキュメント型データベースはMongoDBが有名です。Firebaseはデータ全体がJSONです。Firebaseのデータをビジュアルに編集できるWebページを提供しています。
これだけなら単にMongoDBをWebサービスにしても同じことです。しかし、Firebaseが面白いのはAngularJSなどのクライアントサイドフレームワークとの相性が抜群だということです。AngularJS用にAngularFireというライブラリを提供しています。AngularFireでは、MVCをクライアントサイドで実現します。AngularFireのModelは、DOM、Firebaseと3方向に同期されます。その結果、クライアント単体でアプリケーションを実現します。つまり、アプリケーショサーバがいらないのです。

Firebaseにはホスティングの機能があり、Webサーバとしても働きます。しかし、それはWebページを配信するためのものであり、サーバ側で処理するアプリケーションサーバを意味しません。
Webアプリケーションは3層モデルを採用してきました。3層からアプリケーションサーバが除かれると2層のクライアントサーバに戻ります。しかし、アプリケーション配信が不要などWebアプリのメリットは維持しています。
なお、その他のJavaScriptでも同じく2層モデルを構成できます。しかし、JavaScript以外の言語では従来通り3層モデルとなります。
2層化にはセキュリティの問題があります。クライアントに自由にデータベースを操作することを許すので、不正アクセスも簡単です。よって、読み取り専用データを除けば、必ず認証(Authentication)・承認(Authorization)と組み合わせる必要があります。

FirebaseではOAuthのライブラリも提供しています。GoogleでログインするWebアプリも簡単に作れます。OAuthのクライアントIDおよび秘密鍵はFirebase側に登録され、リダイレクトページも用意されます。承認はFirebase側でセキュリティルールを設定することで実現します。一般的には、ログインしたユーザだけがアクセスできるように設定します。
問題となるのは、クライアントコードが不正に改変された場合です。特にOAuthを使うと、例えばGogoleのユーザなら誰でも不正アクセスすることができます。そのため、OAuthに加えて独自の絞り込みが必要になります。なお、OAuthには送信元が登録されるので、クライアントコードをコピーしてもOAuth認証を回避できるわけではありません。

実際に、AugularFireで認証付きアプリを作成しようとすると、情報が少ないことに驚きます。そこで、具体的な方法を紹介します。ただし、この方法は試行錯誤の結果なので、必ずしもベストあるいは公式に推奨される方法とは限りません。

ポイントは$firebaseと$firebaseAuthの2つを使う点です。
$firebaseAuthからFirebaseデータにアクセスできるかと思って試したのですが、どうやら認証専門のようです。二重の参照は美しくありませんが、やむをえません。$firebaseAuthが$firebaseを継承してくれればよいのですが。
Googleのメールアドレスの中で@toyo.jpを持つユーザだけに限定しています。auth.uidは意味不明の数字なので、{scope: "email"}がかかせません。該当しないユーザは$unauthしてしまえばログインを拒否したことになります。ちなみにメールアドレスはFirebaseのnameにできません。メールアドレスに含まれる特殊記号がはじかれます。

var app = angular.module("sampleApp", ["firebase"]);
app.controller("SampleCtrl", ["$scope", "$firebase", "$firebaseAuth", function($scope, $firebase, $firebaseAuth) {
  var ref = new Firebase("https://minoru-uehara.firebaseio.com/");
  var auth = $firebaseAuth(ref);
  $scope.logout = function() {
    auth.$unauth();
  };
  $scope.login = function() {
    auth.$authWithOAuthPopup('google', {scope: 'email'});
  };
  auth.$onAuth(function(authData) {
    $scope.authData = authData;
    if (authData) {
      var mail = authData.google.email;
      if (! (/@toyo.jp$/i).test(mail)) {
        auth.$unauth();
      } else {
        var denys = [
          /^[A-Za-z]{2}[0-9]{2}[A-Za-z0-9]+@toyo.jp$/i,
          /^[A-Za-z][0-9][A-Za-z0-9]+@toyo.jp$/i
        ];
        for(var i = 0; i < denys.length; i++) {
          if (denys[i].test(mail)) {
            auth.$unauth();
          }
        }
      }
      // unauthさせずに到達すればOK
      // 共有データ
      $scope.data = $firebase(ref.child('data')).$asObject();
      // プライベートデータ
      $scope.users = $firebase(ref.child('users').child(authData.uid)).$set({email: authData.google.email});
    }
  });
}]);


2014年10月29日水曜日

7-11のコーヒー

いまさら感があるかもしれないが、7-11のコーヒーが美味しい。
以前にスターバックスとマクドナルドを比べたことがある。あくまで個人の嗜好によるが、私だったら値段が高くてもスターバックスを選ぶ。
マクドナルドのコーヒーは、やはりアメリカンだとしか思えない。
私は、エスプレッソをがぶ飲みしたい人なので一般的な嗜好でないのは承知している。それを考慮しても、やや薄い、ものたりないと感じる。その当時は値段相当なので、それもよいかと思った。
しかし、7-11コーヒーが同じ値段で登場したとなると、マクドナルドのコーヒーは全く意味がなくなる。
7-11コーヒーの最大のポイントは香りだろう。香りだけならスターバックスを凌駕しているのではないかと思う。コーヒーにとって香りは大事だとは思っていたが、これほど実感させてくれたものはない。
味としては、濃すぎることもなく、薄すぎることもない。私の嗜好からは薄い方に入るが、それでも決して薄すぎない。それでいて香るのだから、うまいとしかいいようがない。
最近、スターバックに行かなくなった。理由の一つはもちろん7-11コーヒーであるが、それだけではない。スターバックスは、行っても座れないことが多い。7-11は最初から座らないので気にならないが、座らないと飲めないのに座れないのだから行っても無駄という気になる。人気なのもよいが、かなり損をしているように思う。
7-11には駐車スペースがあるので、その一部を使って晴れた日にはオープンカフェを催してもよいのではないかと思う。まあ、たまり場にならないように注意する必要があるかもしれないが。

2014年4月20日日曜日

人工知能のブレークスルー

ここ数年、人工知能関係のトピックが多く話題になった。
チェスの名人に勝ったり、クイズを解いたり、将棋も強くなった。
モンテカルロ法の登場とそれを実現するシステム技術のおかげだ。
モンテカルロ法は経験的に決め打ちされていた評価関数を動的に最適化した。
しかし、モンテカルロ法を実現するには多くの資源を必要とした。
それが解決できたために急速に賢くなった。
計算資源はプロセッサとメモリに大別できる。
プロセッサの能力は確かに高くなったが、それ以上にメモリ(特にストレージ)が大きくなった。
後者の発達によって計算結果を保持することが可能となり、乱暴な全解探索も現実味を帯びてきた。
プロセッサやメモリなどの製造技術は人工知能研究者の都合で変わるものではない。
適切な時代でなければ実現しないアイデアがある。時代によってアイデアの価値が変わることがある。

コンピュータに音読させるには

文字を音声に変える機能(ナレーション)は多くの人が望んでいる。
しかし、平板な音声は聞き取りにくく、決して十分とはいえない。
文字を音声に変えるには、文字列を形態素解析(簡単にいえば単語に分けること)し、音素に変換し、連結して再生する。この結果、いかにもロボット的な音声が再生される。
人間とロボットの違いは、感情表現の豊かさにある。
単に音素を求めただけでは感情要素が足りない。
具体的には、速さ、大きさ、高さであるが、同じ文を読み上げても心の動きで変わってくる。
この現状を改善するには、まず速さ、大きさ、高さ等をユーザが設定できる音声エディタが必要になる。機械的な音読データを人間が編集し聴きやすくする。
このままでは人手による解であり、決して十分とはいえない。
次に、作成した感情付き音声データを、単なる音声データだけでなく、その感情情報を含めて流通させる必要がある。
それらの感情データを多数集積して、文脈を機械学習させると、ある程度文脈に応じて感情移入した音声を再生できるようになるだろう。
これはビッグデータによる解決法だ。
感情付き音声編集ソフトとその再生ソフトをクラウドで提供すれば、感情データを収集することができる。利用者と提供者の利害が一致し、両者に有益なビジネスモデルとなる。
方法論的によくある誤りは、データを収集する前に、感情を付加するアルゴリズムを作成しようとする(できると思う)ことだ。それは典型的な根拠なき主張である。

2014年3月5日水曜日

DR-C125の自炊における課題

DR-C125はCanonの普及版スキャナーだ。
いうなれば最も売れ筋だと言える。
前々回の記事でDR-C125で自炊する際の注意点を述べた。
ここでは、問題点を述べる。
文庫本を上向き廃紙すると、静電気で紙が密着し、紙詰まりを起こしやすい。
下向き廃紙すると、ページ順が1/2, 3/4, ...から2/1, 4/3, ...のように裏返る。それだけならよいが、廃止済みの紙をそのままにしておくと挿入されて順序が変わることがある。後でスキャンミスがあったとき、該当ページを探すの結構な手間がかかる。
これは致命的ではないものの、かなり大きな問題点だ。実際、かなり面倒なので古いDR-2150Cに戻ってしまった。
ちなみに、A4サイズや紙質によっては問題ない。自炊用というよりビジネス用というべきだろう。
下向き廃紙を正しい順序で確実に保持してくれるアダプターを別売りすればよいと思う。面積を広げるのではなく、高さでカバーするような方向で設計すれば、あまりメリットを最大限に生かせるだろう。

自炊からKindleへ

Kindle版書籍が充実してきた。
(宅配不要で)読みたい本がすぐに読め、自炊の手間も減り、Amazonで保存もしてくれる。
とても便利だ。
昔の本がKindle版として復刻されているのもよい。
角川文庫の横溝正史が、あのおどろおどろしい表紙で復刻されているので、おもわず大人買いをしてしまった。老後の楽しみにとっておく。
しかし、まだ課題はある。
まず、すべての書籍がKindle化されているわけではない。これは時代の流れとともに解消されるだろう。紙の本はなくならないが、減っていくだろう。
Kindle書籍は基本的に共有が難しい。個人の複数端末ではクラウドで共有できるが、別人がアクセスするのは著作権的にNGだろう。しかし、一般的に家庭内共用は多くの場合認められている。電子化により厳密化されると家族内家庭内共用も難しくなる。端末自体の共用で補う必要がある。特定の端末にだけ閲覧可能なリストの作成などといった機能をクラウド側で提供する必要があるだろう。
最後に、Kindle書籍を図書館はどう扱うのだろう。端末貸し出しが現実的だろうが、あまりにコストが高い。

2014年1月27日月曜日

DR-C125

書籍の整理のために、いわゆる自炊(スキャン)をしている。
お気に入りのスキャナーはCanon DR-2510Cだった。
しかし、もはや生産終了して入手できない。
代わりとなる製品がDR-C125だ。
機能的にはDR-2510Cの上位互換ともいえるが、同じように使うには少しコツがいるようだったので、紹介しておく。
個人的に、自炊モードは24ビットフルカラー、300dpi、両面を選択している。これが様々なビューワで閲覧するのにちょうどよい。
DR-C125の標準設定はかなり画質が悪い。おそらく白黒のビジネス文書を対象としているのだろう。
そこで、手動設定を行うのだが、上記のようにスキャナを設定しても常に画質がDR-2510Cに劣る。
この原因は出力時の高圧縮モードにあった。出力時設定で標準圧縮に変更するとDR-2510Cと同等の画質となった。
確かに高圧縮モードの圧縮率は高い。しかし、不可逆圧縮のようで、画質まで低下してしまう。そのような圧縮はあまり望まれないのではないだろうか。画質低下を許容するなら、最初から低解像度でスキャンすればよいのだから。
ちょっと腑に落ちないことだったので、メモしておいた。