2014-04-24 20 views
0

我想製作一個ScalaInterceptor,它尋找一個X-Forwarded-Proto標題,所以基本上如果它在製作或代理後面,那麼Play!自動重定向到SSL。使用ScalaInterceptors捕捉Play中的HTTPS! 2.2?

我遇到了編譯這個代碼的問題,我也不確定這是否可以與SecureSocial插件一起使用。我們沒有在SecureSocial.conf中設置SSL = true的具體原因,我不會在此處介紹。

下面是我在我的Global.scala

def WithHttpsRedirect[A](action: Action[A]): Action[A] = { 
    Action(action.parser) { request => 
     val result = action(request) 
     request.headers.get("X-Forwarded-Proto").collect { 
     case "https" => 
      result 

     case "http" => 
      val url = "https://"+request.host+request.uri 
      Redirect(url) 

     } getOrElse { 
     result 
     } 
    } 
    } 

    override def onRouteRequest(request: RequestHeader): Option[Handler] = { 
    super.onRouteRequest(request).map { handler => 
     handler match { 
     case a: Action[_] => WithHttpsRedirect(a) 
     case _ => handler 
     } 
    } 
    } 

我得到一個編譯器錯誤getOrElse後:

[error] found : scala.concurrent.Future[play.api.mvc.SimpleResult] 
[error] required: play.api.mvc.Result 
[error]   result 
[error]  ^

你的幫助是極大的讚賞!

回答

0

改變了我的法攻,而是實現了一個過濾器,而不是壓倒一切的onRouteRequest

Global.scala

object Global extends WithFilters(HttpsFilter) with GlobalSettings

然後HttpsFilter.scala

import play.api.mvc.Results._ 
import play.api.mvc.{SimpleResult, RequestHeader, Filter} 
import scala.concurrent._ 
import ExecutionContext.Implicits.global 

object HttpsFilter extends Filter { 

    def apply(next: (RequestHeader) => Future[SimpleResult])(request: RequestHeader): Future[SimpleResult] = { 
    request.headers.get("X-Forwarded-Proto").collect { 
     case "https" => 
     next(request) 

     case "http" => 
     val url = "https://"+request.host+request.uri 
     Future{ Redirect(url) } 

    } getOrElse { 
     next(request) 
    } 
    } 

} 
0

替換:

Action(action.parser) { request => 

有:

Action.async(action.parser) { request => 

你做也需要更換:

Redirect(url) 

有:

Future.successful(Redirect(url)) 
+0

我其實只是製作了一個擴展過濾器,我會發布它:) – crockpotveggies