3

私のサービスのすべての API 呼び出しは、マルチパート ボディで渡されるパラメーターを含む HTTP POST です。現在、私の認証は次のようになっています

formField("token".as[String]) { token =>
   authorize(isAuthorized(token)) {
      .... my other routes here
   }
}

しかし、それはあまりにも冗長に見えます。理想的には、次のようなものが必要です。

myAuthorization {
   .... my other routes here
}

だから私はそれを次のように書きます:

def myAuthorization: Directive0 = 
  formField("token".as[String]).require(isAuthorized(_))

しかし、リクエストで noをmyAuthorizationスローするようにするにはどうすればよいでしょうか。AuthorizationFailedRejectiontoken

4

2 に答える 2

6

エクストラクタを使用してスプレー ディレクティブを作成するのが好きです。私のプロジェクトの単純化された例:

def loggedInUser: Directive[Option[User] :: HNil] = headerValue {
    case Cookie(cookies) => cookies.find(_.name === usrCookie) ∘ extractUserFromCookie
    case _ => None
} | reject(NoUserLoggedInRejection)

def authOpt(usrOpt: Option[User], usr: String): Directive0 =
    authorize(usrOpt.filter(_.login ≠ usr).isEmpty)

次に、ルーティング ファイルでエクストラクタを使用できます。

pathPrefix("path") {
    loggedInUser { user =>
      authOpt(user, Clients.client) {
        path("path") {
          get {
            complete {
              html.page() // i'm using Twirl as a fe engine
            }
          }
        }
      }
    }

ユーザーがログインしていない場合は、個別に処理される拒否をスローします。

implicit val customRejectionHandlers = RejectionHandler {
  case NoUserLoggedInRejection :: _ =>
    ctx => ctx.redirect("/auth", StatusCodes.SeeOther)
}

セキュリティの例の場合、それは最善ではありませんが、十分に明確だと思います

追加した

headerValueコメントからのディレクティブの例:

// Lets define a extractor for the Host header from the request
val hostExtractor: HttpHeader => Option[String] = {
  case Host(host, port) => Some(host)
  case _ => None
}

// Then some path
val route = {
  path("somePath") {
    post {
      headerValue(hostExtractor) { host =>
        complete(host)
      }
    }
  }
}

そのようなディレクティブのほとんどはextract、 type: の関数を取り、RequestContext ⇒ Tを返すディレクティブを介して実装されますT。たとえば、次の方法headerValueでも実装されますextract

extract(_.request.headers.mapFind(protectedF)).flatMap {
  case Some(Right(a))        ⇒ provide(a)
  case Some(Left(rejection)) ⇒ reject(rejection)
  case None                  ⇒ reject
}
于 2013-06-28T09:27:11.033 に答える