我正在尝试为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);
}
});
});
答案 0 :(得分:2)
您没有指定访问受保护网址的方式(dev.driz.co.uk/basic/locked)。你确定你正在这样做的方式是正确设置请求标头吗?您需要Base64编码用户名/密码。
当您的第一个请求失败时,浏览器会跳出提示并成功,这意味着浏览器会第二次为您正确执行此操作。
查看您的请求标题,以查看您第一次发送的内容以及浏览器发送的内容。
当基本身份验证失败时,您的服务器会发送一个带有标题401
的{{1}},该标题会从浏览器中获取并显示提示。这是所有浏览器的正常行为,因为年龄,你不能改变它。
关于取消和重定向到登录的问题,Auth在2.4之后对本书中突出显示的API进行了一些更改。在2.4版之前,您总是被重定向到loginAction。
最后,让WWW-Authenticate:Basic
通过正确设置为您完成工作,而不是像您建议的代码那样尝试自己硬连接响应。你也不应该曾在cakephp中使用php的Auth
,而是使用header()
。
在Q2中回答,你不能让Basic和401不能触发提示。更改所需的身份验证标头(可能通过设置类似Basic-x而不是Basic的名称)或者在发生故障时不发送响应代码401,但是发送即200或400并添加解释该情况的错误消息。