将一个Play 2应用程序保留在heroku上

时间:2014-01-18 16:59:47

标签: heroku playframework playframework-2.0 cloud

我正在使用Heroku来托管Play 2应用程序,以便进行测试和游戏。我希望应用程序在这一点上是“私有的”,这意味着应用程序的每个方面都应该只对某些用户可见。

通常情况下,我只会使用一个单一用户/密码的htaccess文件,但这当然是Apache的特定内容,在这种情况下无法帮助我。

  • 保护不一定要“强”。主要目的是远离机器人和随机访客
  • 如果我不必“污染”我的播放应用程序的代码,那将是很棒的。我更愿意有一些外部机制来实现这一目标。如果除了使用游戏本身实现它之外别无其他方法,解决方案应该与我的游戏应用程序的其余部分松散耦合。

我怎么能实现这个目标?

编辑:强调它:我想要实现的内容不会成为生产模式中最终应用程序的一部分。所以它既不是超级安全,也不是超级工程。

2 个答案:

答案 0 :(得分:2)

我不认为Heroku为此提供了解决方案。我最终实现了一个Basic access authentication过滤器并在Global对象中使用它。它看起来像这样

class HerokuHttpAuth extends Filter {

  object Conf {
    val isStaging = true // read a config instead of hard coding
    val user = "theusername"
    val password = "thepassword"
  }

  override def apply(next: RequestHeader => Result)(request: RequestHeader): Result = {

    if (Conf.isStaging) {
      request.headers.get("Authorization").flatMap { authorization =>
        authorization.split(" ").drop(1).headOption.filter { encoded =>
          new String(org.apache.commons.codec.binary.Base64.decodeBase64(encoded.getBytes)).split(":").toList match {
            case u :: p :: Nil if u == Conf.user && Conf.password == p => true
            case _ => false
          }
        }.map(_ => next(request))

      }.getOrElse {
        Results.Unauthorized.withHeaders("WWW-Authenticate" -> """Basic realm="MyApp Staging"""")
      }
    } else {
      next(request)
    }
  }
}

答案 1 :(得分:2)

Adreas示例是正确的,但它来自于播放2.1和播放2.2,Filter.apply的签名已经改变了一点,这应该更适合2.2:

class BasicAuth extends Filter {

  val username = "stig"
  val password = "secretpassword"

  override def apply(next: RequestHeader => Future[SimpleResult])(request: RequestHeader): Future[SimpleResult] = {
    request.headers.get("Authorization").flatMap { authorization =>
      authorization.split(" ").drop(1).headOption.filter { encoded =>
        new String(org.apache.commons.codec.binary.Base64.decodeBase64(encoded.getBytes)).split(":").toList match {
          case u :: p :: Nil if u == username && password == p => true
          case _ => false
        }
      }.map(_ => next(request))

    }.getOrElse {
      Future.successful(Results.Unauthorized.withHeaders("WWW-Authenticate" -> """Basic realm="MyApp Staging""""))
    }
  }
}