LoginSignup
11
11

More than 5 years have passed since last update.

Play frameworkで独自のActionを作って認証処理を挟んだり、出力を変える

Last updated at Posted at 2015-08-06

やりたいこと

通常のActionを利用するとこんな感じ

def hoge(mage: Int) = Action(parse.json) {
  // do something
  Ok
}

いい感じの認証用Actionを用意して、認証失敗なら共通のレスポンスを自分で設定したい
(Jsonを出力するとか)

// 認証が通らなければ {"auth" -> "failed"} を返す
def hoge(mage: Int) = AuthAction(parse.json) {
  // do something
  Ok(Json.obj("auth" -> "success"))
}

独自Actionを作る

まずはActionBuilderを継承したobjectを適当な所に作る

import play.api.mvc.{ActionBuilder, Request}
import scala.concurrent.Future

object AuthAction extends ActionBuilder[Request] {

  // invokeBlockはabstractなので、実装しないといけない
  override def invokeBlock[A](request: Request[A], block: (Request[A]) => Future[Result]): Future[Result] = {
    // do anything
  }

当然何も返さないと怒られるので、レスポンスを用意してあげる。

import play.api.mvc.{ActionBuilder, Request}
import scala.concurrent.Future

object AuthAction extends ActionBuilder[Request] {

  override def invokeBlock[A](request: Request[A], block: (Request[A]) => Future[Result]): Future[Result] = {
    println("hogehoge")
    block.apply(request)
  }

試しにこのAuthActionを使えば処理は何も変わらないけどhogehogeがコンソールに表示されていることを確認できる。

認証処理

sessionを使った適当な認証を書いてみる

import play.api.mvc.{ActionBuilder, Request}
import scala.concurrent.Future

object AuthAction extends ActionBuilder[Request] {

  override def invokeBlock[A](request: Request[A], block: (Request[A]) => Future[Result]): Future[Result] = {
    request.session.get("foo") == "bar" match {
      case true => // 認証OK
      case _ => // 認証NG
    }
    block.apply(request)
  }

自分でレスポンスを設定

あとは認証失敗時のレスポンスを自分で作れればOK

import play.api.mvc.{Results, ActionBuilder, Request, Result}
import scala.concurrent.Future
import play.api.libs.json.Json

object AuthAction extends ActionBuilder[Request] {

  override def invokeBlock[A](request: Request[A], block: (Request[A]) => Future[Result]): Future[Result] = {
    request.session.get("foo") == "bar" match {
      case true => block.apply(request)
      case _ => Future.successful(Results.Status(401).apply(Json.obj("auth" -> "failed")))
    }
  }

Unauthorized ... Results.Status(401).apply() という事になるので、
出てきたResultを適当にFutureで包んであげればよいことになる

これで要認証Actionと認証不要Actionを手軽に使い分けられる

11
11
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
11
11