SPAとログイン認証

ドクジリアン柔術少女 すから☆ぱいそん

ログインが必要なアプリケーションを SPA(Singe Page Application) として作る時に、「ログインされていなければログイン画面に飛ばす」入り口の処理をどこでやるかについての考察

典型的な Webアプリケーションでは、ログインが必要なURLへのリクエストが来たらセッション変数なりなんなりをデータベースと照合してログイン済みの状態でなければログイン画面にフォワードなりリダイレクトなりしてログイン処理に回す(そこからどう戻ってこさせるかは工夫する)という処理をサーバ側で行う。

いっぽう、AngularJSなどで作る SPAの場合は SPAらしくクライアント側で認証周りから行いたくなるものだけど、これを真面目にやろうとすると結構面倒なことを考えなければならない。なにぶん Ajaxは常に非同期で行われるものだから、SPAの開始部分でユーザーがログイン状態にあるかどうかをサーバーに問い合わせる処理を記述したところで、その問い合わせが行われている間に別の処理が走りだしてしまう。そこらをちゃんと考えて実装しないとログインされていること前提で呼び出されるはずのAPIや画面が先走って呼び出されてしまうわけだね。

これにJS側で頑張って対策しようとすればするほどわかりにくいプログラムになっていくのは目に見えているので、自分のところではログイン周りのたらい回しだけは古典に則りサーバー側でやるようにして、クライアント側では「認証されていること前提」の処理だけを記述するようにしている。これでJS側のコードはスッキリきれい。

下記はサーブレットフィルタの例。ここだけ取り上げると古典的すぎてSPA関係ないね。

class AuthenticationRequiredSPAFilter {
  private var servletContext:ServletContext = _

  override def init(filterConfig: FilterConfig): Unit = {
    servletContext = filterConfig.getServletContext
  }

  def isAuthenticated(request: ServletRequest):Boolean = {
    // ここでログイン済みかどうかを判断
  }

  override def doFilter(request: ServletRequest, response: ServletResponse, filterChain: FilterChain): Unit = {
    if (isAuthenticated(request)) {
      // ログイン済みだったらスルー
      super.doFilter(request, response, filterChain)
    } else {
      // 未ログインならログイン画面にフォワードする
      servletContext.getRequestDispatcher("/login.jsp").forward(request, response)
    }
  }
}

ログイン画面に飛ばすのだけはサーバ側でやるとしてもも、ログイン画面自体の実装は(メインのアプリケーションとは別のものとして)SPAの作法で作れば良いよ。

いつもだったら Twitterで書捨ててしまうような些細なことをブログに書いてみるテストでした。

同じカテゴリの記事

カテゴリ ドクジリアン柔術少女 すから☆ぱいそん の記事一覧
企業向けニッチ製品にフリーミアムは通用するのか 2015年1月9日
【宣伝】ドンキに行ったら外国人がすごかった(メディアファクトリー社刊) 2014年12月18日
オタクと常識人 2014年12月5日
テキトーな人達と、不必要に細かい人達 2014年11月30日

お勧めカテゴリ

英語でアニメ観ようず
なじみ深い日本製アニメの英語版DVDで、字幕と音声から英語を学びましょうという趣旨のシリーズ記事です。
ScalaのようでJavaだけど少しScalaなJSON API
Scalaと Spring Frameworkを使って REST的なJSON APIを実装してみましょう。
ドクジリアン柔術少女 すから☆ぱいそん
代表 嶋田大貴のブログです。写真は神仏に見せ金をはたらく罰当たりの図