2009-07-08 33 views
25

En mi controlador, verifico una condición para ver si el usuario puede hacer algo. Si la verificación falla, quiero enviar un 403 de vuelta al navegador. ¿Cómo hago eso en Cakephp?¿Cómo se especifica un código de estado HTTP en Cakephp?

+0

También vale la pena señalar que CakePHP 3x es [PSR-7] (https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-7-http-message.md) obediente. – jtrumbull

Respuesta

36

EDIT - Esta pregunta es bastante antigua y cubre diferentes versiones del marco de CakePHP. A continuación se muestra un resumen de a qué versión se aplica cada respuesta. No olvide votar sobre la solución que más ayuda.

EDIT # 2 - A more detailed answer para CakePHP 2.x ha sido agregado por Mark37.


Al observar el correspondiente API code del comentario anterior, parece que se puede llamar Controller::header($status) para emitir una cabecera sin redirección. En su caso, el uso adecuado es más probable:

$this->header('HTTP/1.1 403 Forbidden'); 
+0

del usuario. Además, el código anterior solo muestra el encabezado, por lo que puede querer finalizar la ejecución con 'return false',' die', 'exit', o algo similar. – deizel

+0

Esto responde la pregunta con mayor precisión que mi respuesta. Aún así, creo que es útil poder redirigir al usuario a una página personalizada en este caso, es mejor que una página en blanco 'el servidor respondió esto'. –

+0

Al observar el cuerpo de ese método, parece ser una envoltura alrededor de una función incorporada llamada encabezado. – allyourcode

3

Tal vez algo in this section of the cakephp manual puede ayudarle.

redirección (string $ url, número entero $ status, booleano $ salida)

El método de control de flujo que va a utilizar con más frecuencia es redirigir(). Este método toma su primer parámetro en el formulario de una URL relativa a CakePHP. Cuando un usuario ha realizado un pedido con éxito, es posible que desee redireccionarlo a la pantalla de recibo . El segundo parámetro de redirect() le permite definir un código de estado HTTP para acompañar el redireccionamiento . Puede usar 301 (movido permanentemente) o 303 (vea otro), dependiendo de la naturaleza del redireccionamiento .

El método emitirá una salida() después de la redirección a menos que establezca el tercer parámetro en falso.

+0

Pero no quiero volver a enviar un código de estado 3xx. Incluso si esto funciona, parece incorrecto. – allyourcode

+1

Puede devolver cualquier código de estado, los 303 son solo un ejemplo. –

+0

Esto es perfecto para los códigos de estado de redireccionamiento 3xx. Definitivamente una idea horrible para todo lo demás, como el 403. –

7

Al volver a examinar esta cuestión, y leer el comentario de Adriano en mi respuesta anterior (con respecto a redirigir al usuario a una página amigable), he llegado con una nueva solución .

Dentro de un controlador puede llamar al $this->cakeError('error404') para generar una página amigable 404. Esto se puede personalizar (como con otros errores) creando un archivo en 'app/views/errors/error404.ctp'.

Después de tener una mirada más cercana a la code for cakeError, mi recomendación es intentar extender la torta de ErrorHandler mediante la creación de un archivo en 'app/error.php' o (posiblemente más preferible) 'app/app_error.php'.

El código para su error403 (imitando el error404 code) podría ser el siguiente:

class AppError extends ErrorHandler { 
    function error403($params) { 
     extract($params, EXTR_OVERWRITE); 
     $this->error(array(
      'code' => '403', 
      'name' => 'Forbidden', 
      'message' => sprintf(__("Access was forbidden to the requested address %s on this server.", true), $url, $message))); 
      $this->_stop(); 
    } 
} 

Usted debe también ser capaz de proporcionar una vista personalizada de este error mediante la creación de 'app/views/errors/error403.ctp'. Aquí es una versión modificada de la error404 view:

<h2><?php echo $name; ?></h2> 
<p class="error"> 
    <strong>Error: </strong> 
    <?php echo sprintf(__("Access was forbidden to the requested address %s on this server.", true), "<strong>'{$message}'</strong>")?> 
</p> 
+0

¡Buena respuesta! Esto es algo que no sabía que podrías hacer con Cake. –

11
$this->response->statusCode(403); 

fijará el código de estado cuando la torta está lista para enviar la respuesta. CakeResponse :: send() espera enviar el código de estado y el mensaje, por lo que en mis pruebas creo que se sobrescribió el uso de header(). utilizando $this->header('HTTP/1.1 400 Bad Request') no funciona bien porque la torta espera que cualquier llamada a $this->header se divida en dos puntos por ejemplo: $this->header('Location: ...')

+2

+1 para una respuesta de CakePHP 2.x ('$ this-> response -> ...') que puede ayudar a los visitantes actuales de Google, etc. (Para aquellos visitantes: las respuestas de 2009 son para el CakePHP 1.x base de código) – deizel

+0

Esto funcionará, pero las excepciones son preferidas para este tipo de situaciones en CakePHP 2. Anulan la ejecución del controlador de inmediato y activan el proceso estándar de manejo de errores. –

+3

Las excepciones son mejores para los estados 4xx y 5xx, pero si necesita (por ejemplo) devolver 201 a una solicitud POST, este podría ser el camino a seguir. – eaj

9

estoy añadiendo en mi dos centavos aquí porque no creo que ninguna de estas respuestas haya cubierto este tema tan exhaustivamente como me hubiera gustado (al menos para Cake 2.x).

Si usted quiere lanzar un estado de error, utilice las clases de excepción (como se ha mencionado en otras respuestas):

throw new BadRequestException(); // 400 Bad Request 

// Or customize the code... 
throw new BadRequestException('Custom error message', 405); // 405 Method Not Allowed 

Dato curioso: Pastel hará automáticamente un error mágica renderizado incluso para llamadas REST vía la clase ExceptionRenderer. Lo más divertido es que se basa en el código de estado , no en el hecho de que se haya lanzado un Exception, por lo que si establece el código de estado en> 400 por su cuenta, es probable que reciba mensajes de error incluso si no los quería.

Si desea devolver un código de estado específico para un punto final REST JSON/XML, aproveche el nuevo objeto CakeResponse, pero también asegúrese de agregar la variable especial _serialize o terminará con una 'vista not found 'error, ya que Cake intentará encontrar una vista para renderizar su JSON/XML. (Esto es por diseño -. Consulte la clase JsonView/XmlView)

$this->response->setStatus(201); // 201 Created 
$this->set('_serialize', array()); // Value must be something other than null 

Y por último, si desea enviar un estado de no-200 para una página representada con regularidad, sólo puede utilizar el método setStatus() con ninguna otra cosa como se ha mencionado en una respuesta anterior:

$this->response->setStatus(201); 

ACTUALIZACIÓN:

$this->response->setStatus('code'); 

ya no está disponible.Utilice

$this->response->statusCode('code'); 
+1

+1 - He agregado un enlace a su respuesta de la respuesta aceptada anteriormente. – deizel

+0

'CakeRequest' no tiene' setStatus' en ninguna de las versiones 2.x. Si desea establecer códigos de estado en 2.x, debe usar el método 'status' de CakeResponse'. Toma una versión entera del código de estado que desea establecer. –

+0

Gracias @BlakeHair - Creo que cuando escribí esto originalmente, quise escribir 'response' pero escribí' request' en su lugar. –

1

Puede utilizar cakephp response para el mensaje personalizado:

$this->response->header('HTTP/1.0 201', 'custom message'); 
$this->response->send(); 
1

Notas relativas 3.x CakePHP parece que faltan, por lo que para que este completa hilo:

Para CakePHP 3. x uso:

$response = $this->response->withStatus(403); 
return $response; 

Para las versiones anteriores a CakePHP 3.3.x puede usar el mismo st yle como CakePHP 2.x:

$this->response->statusCode('code'); 

Tenga en cuenta que el uso de la función de PHP también trabaja directamente (http_response_code(403); die();), aunque el uso de la response object parece que el método deseado.

Cuestiones relacionadas