CakePHP中的基本身份验证

时间:2014-06-20 17:31:38

标签: cakephp basic-authentication

我正在尝试为CakePHP应用程序设置基本身份验证,以便将其用作即将推出的移动应用程序的API。但是,如果我通过以下内容:

cameron:password@dev.driz.co.uk/basic/locked/

其中,cameron是用户名,密码是密码,其余是域和应用程序。 locked是一种需要身份验证的方法。 (显然,此示例中的密码错误)

(Q1)我会在提示中要求输入用户名和密码...但是用户名和密码实际上是正确的,就好像我将它们输入到他们工作的提示中一样。 。为什么会这样? Haven我刚刚通过了用户名和密码?

我无法看到我在CakePHP中设置它的方式有什么问题。

我在AppController中将Basic Auth设置为:

public $components = array('Auth');

function beforeFilter()
{
    parent::beforeFilter();

    $this->Auth->authorize = array('Controller');
    $this->Auth->authenticate = array('Basic');
    $this->Auth->sessionKey = false;
    $this->Auth->unauthorizedRedirect = false;

}

(Q2)即便如此,我将两个会话设置为false并将重定向设置为false,如果用户取消提示,则会将其重定向到登录页面?关于如何阻止这种情况发生的任何想法?理想情况下,我想发送一个JSON响应或状态代码401(取决于它是否是一个AJAX请求)。

类似于:

if ($this->request->is('ajax')) {

    $response = json_encode(
            array(
                'meta'=>array(
                    'code'=>$this->response->statusCode(401),
                    'in'=>round(microtime(true) - TIME_START, 4)
                ),
                'response'=>array(
                    'status'=>'error',
                    'message'=>'401 Not Authorized'
                )
            )
        );

    // Handle JSONP
    if(isset($_GET['callback'])) {
        $response = $_GET['callback'] . '(' . $response . ')';
    }

    // Return JSON
    $this->autoRender = false;
    $this->response->type('json');
    $this->response->body($response);   

} else {

    header('HTTP/1.0 401 Unauthorized');

}

但是应用程序逻辑会在哪里展示这个?对于需要身份验证且用户失败或取消身份验证的所有请求方法,都需要进行此操作。

(Q3)如果您输入了错误的详细信息,则会再次显示提示,直到您获得正确的用户名/密码或点击取消。如何让它显示错误?

对这三个问题的任何想法(标记为子问题编号)。

更新:这是我将标头发送到API的方式:

"use strict";jQuery.base64=(function($){var _PADCHAR="=",_ALPHA="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",_VERSION="1.0";function _getbyte64(s,i){var idx=_ALPHA.indexOf(s.charAt(i));if(idx===-1){throw"Cannot decode base64"}return idx}function _decode(s){var pads=0,i,b10,imax=s.length,x=[];s=String(s);if(imax===0){return s}if(imax%4!==0){throw"Cannot decode base64"}if(s.charAt(imax-1)===_PADCHAR){pads=1;if(s.charAt(imax-2)===_PADCHAR){pads=2}imax-=4}for(i=0;i<imax;i+=4){b10=(_getbyte64(s,i)<<18)|(_getbyte64(s,i+1)<<12)|(_getbyte64(s,i+2)<<6)|_getbyte64(s,i+3);x.push(String.fromCharCode(b10>>16,(b10>>8)&255,b10&255))}switch(pads){case 1:b10=(_getbyte64(s,i)<<18)|(_getbyte64(s,i+1)<<12)|(_getbyte64(s,i+2)<<6);x.push(String.fromCharCode(b10>>16,(b10>>8)&255));break;case 2:b10=(_getbyte64(s,i)<<18)|(_getbyte64(s,i+1)<<12);x.push(String.fromCharCode(b10>>16));break}return x.join("")}function _getbyte(s,i){var x=s.charCodeAt(i);if(x>255){throw"INVALID_CHARACTER_ERR: DOM Exception 5"}return x}function _encode(s){if(arguments.length!==1){throw"SyntaxError: exactly one argument required"}s=String(s);var i,b10,x=[],imax=s.length-s.length%3;if(s.length===0){return s}for(i=0;i<imax;i+=3){b10=(_getbyte(s,i)<<16)|(_getbyte(s,i+1)<<8)|_getbyte(s,i+2);x.push(_ALPHA.charAt(b10>>18));x.push(_ALPHA.charAt((b10>>12)&63));x.push(_ALPHA.charAt((b10>>6)&63));x.push(_ALPHA.charAt(b10&63))}switch(s.length-imax){case 1:b10=_getbyte(s,i)<<16;x.push(_ALPHA.charAt(b10>>18)+_ALPHA.charAt((b10>>12)&63)+_PADCHAR+_PADCHAR);break;case 2:b10=(_getbyte(s,i)<<16)|(_getbyte(s,i+1)<<8);x.push(_ALPHA.charAt(b10>>18)+_ALPHA.charAt((b10>>12)&63)+_ALPHA.charAt((b10>>6)&63)+_PADCHAR);break}return x.join("")}return{decode:_decode,encode:_encode,VERSION:_VERSION}}(jQuery));

            $(document).ready(function(){

                var username = 'cameron';

                var password = 'password';

                $.ajax({
                    type: 'GET',
                    url: 'http://dev.driz.co.uk/basic/locked',
                    beforeSend : function(xhr) {
                        var base64 = $.base64.encode(username + ':' + password);
                        xhr.setRequestHeader("Authorization", "Basic " + base64);
                    },
                    dataType: 'jsonp',
                    success: function(data) {

                        console.log(data);

                    },
                    error: function(a,b,c) {
                        //console.log(a,b,c);
                    }
                });

            });

1 个答案:

答案 0 :(得分:2)

Q1

您没有指定访问受保护网址的方式(dev.driz.co.uk/basic/locked)。你确定你正在这样做的方式是正确设置请求标头吗?您需要Base64编码用户名/密码。

当您的第一个请求失败时,浏览器会跳出提示并成功,这意味着浏览器会第二次为您正确执行此操作。

查看您的请求标题,以查看您第一次发送的内容以及浏览器发送的内容。

Q2

当基本身份验证失败时,您的服务器会发送一个带有标题401的{​​{1}},该标题会从浏览器中获取并显示提示。这是所有浏览器的正常行为,因为年龄,你不能改变它。

关于取消和重定向到登录的问题,Auth在2.4之后对本书中突出显示的API进行了一些更改。在2.4版之前,您总是被重定向到loginAction。

最后,让WWW-Authenticate:Basic通过正确设置为您完成工作,而不是像您建议的代码那样尝试自己硬连接响应。你也不应该在cakephp中使用php的Auth,而是使用header()

Q3

在Q2中回答,你不能让Basic和401不能触发提示。更改所需的身份验证标头(可能通过设置类似Basic-x而不是Basic的名称)或者在发生故障时不发送响应代码401,但是发送即200或400并添加解释该情况的错误消息。