You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Play Framework 2.6(Scala):如何阻止URL直接访问页面并跳转错误页?

解决方案:禁止直接通过URL访问Play Framework页面

针对你用Play 2.6 + Scala开发的场景,要实现「直接输入URL(如/home)跳转到错误页,而非目标页面」的需求,这里有两种实用方案,你可以根据实际场景选择:

方案一:检查HTTP Referer头(简单快速)

直接通过URL输入的请求,通常不会携带合法的Referer头(或者Referer不是你的网站域名)。我们可以利用这一点,创建一个自定义的Action过滤器,拦截不符合要求的请求。

步骤1:创建自定义ActionBuilder

在项目中新建一个类,实现自定义的Action逻辑:

import play.api.mvc._
import scala.concurrent.{ExecutionContext, Future}

class RefererCheckedAction(parser: BodyParsers.Default, ec: ExecutionContext) extends ActionBuilderImpl(parser) {
  override def invokeBlock[A](request: Request[A], block: Request[A] => Future[Result]): Future[Result] = {
    // 获取当前网站的域名(也可以硬编码成"localhost:9000",但动态获取更灵活)
    val allowedHost = request.host
    // 获取请求的Referer头
    val requestReferer = request.headers.get("Referer")

    requestReferer match {
      // 如果Referer存在且包含我们的域名,允许执行原Action
      case Some(referer) if referer.contains(allowedHost) => block(request)
      // 否则返回错误页(这里替换成你自己的错误视图)
      case _ => Future.successful(Results.BadRequest(views.html.error()))
    }
  }
}

步骤2:在控制器中使用自定义Action

通过依赖注入引入这个自定义Action,替换原来的默认Action:

import play.api.mvc._
import javax.inject.Inject

class HomeController @Inject()(
  val controllerComponents: ControllerComponents,
  refererCheckedAction: RefererCheckedAction
) extends BaseController {

  // 现在只有通过站内跳转的请求才能访问首页
  def index() = refererCheckedAction { implicit request =>
    Ok(views.html.home())
  }
}

注意事项

  • 部分浏览器可能不会发送Referer头(比如隐私模式),这种情况下会误判为直接访问
  • Referer可以被伪造,所以这个方案适合普通场景,对安全性要求极高的场景建议用方案二

方案二:通过Session会话标记(更可靠)

这种方法通过给合法进入的用户设置Session标记,只有携带有效标记的请求才能访问目标页面,避免了Referer的局限性。

步骤1:设置入口页面的Session标记

先创建一个合法的入口页面(比如登录页、欢迎页),在这个页面的Action中设置Session:

def entry() = Action {
  // 进入这个页面时,给Session添加一个验证标记
  Ok(views.html.entry()).withSession("valid_access" -> "granted")
}

步骤2:在目标页面检查Session标记

修改HomeController的index方法,先验证Session中的标记:

def index() = Action { implicit request =>
  request.session.get("valid_access") match {
    // 如果Session中有有效标记,允许访问首页
    case Some("granted") => Ok(views.html.home())
    // 否则跳转到错误页
    case _ => Results.NotFound(views.html.error())
  }
}

优化建议

  • 可以给Session设置过期时间,避免标记永久有效
  • 生产环境中建议开启Session的HttpOnly和Secure属性,提升安全性

最后,routes文件保持你原来的配置即可:

GET /home controllers.HomeController.index()

内容的提问来源于stack exchange,提问作者mohamedali10

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 07:08:55