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
相关产品推荐
相关产品推荐

