AngularJs/PHP中JWT认证请求Authorization头丢失问题求助
嘿,作为安全领域新手遇到这种问题很正常,我来帮你拆解下这个诡异的现象,一步步解决它:
问题根源拆解
你已经在AngularJS里全局配置了Authorization头,第一个请求能正常携带,但第二个同类型的GET请求却丢了头,而且移除后端的header('HTTP/1.0 401 Unauthorized');就恢复正常——这大概率是CORS预检请求处理不当,加上AngularJS的一个默认行为导致的:
- 预检请求(OPTIONS)被401拦截:浏览器在发送带自定义头(比如Authorization)的跨域请求前,会先发送OPTIONS预检请求,确认后端允许这个请求。如果你的后端在OPTIONS请求时也返回了401,浏览器会直接终止后续的实际请求,甚至会让AngularJS后续不再携带认证头。
- AngularJS自动清除无效认证头:当AngularJS收到401响应时,会默认移除全局设置的Authorization头,避免重复发送无效的令牌,这就导致后续请求(比如你的第二个GET请求)不再带这个头了。
具体解决步骤
1. 先给OPTIONS请求开绿灯
你的后端已经加了CORS头,但要专门处理OPTIONS请求,让它直接返回200,不要走业务认证逻辑。在api.php最开头加上这段代码:
// 优先处理CORS预检请求 if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') { header('Access-Control-Allow-Origin: *'); header('Access-Control-Allow-Methods: GET, POST, PATCH, PUT, DELETE, OPTIONS'); header('Access-Control-Allow-Headers: Origin, Content-Type, Authorization'); header('HTTP/1.1 200 OK'); exit; // 直接退出,不要执行后续的认证逻辑 } // 下面再写你的业务代码和认证判断(包括返回401的逻辑)
这样浏览器的预检请求能正常通过,后续的GET请求就会乖乖带上Authorization头了。
2. 用拦截器确保认证头不丢失
如果后端确实需要返回401(比如令牌过期),可以用AngularJS的HTTP拦截器,每次请求都重新设置Authorization头,避免被框架自动清除:
// 创建一个认证拦截器 app.factory('authInterceptor', ['$q', '$window', function($q, $window) { return { // 每次请求前都重新设置头 request: function(config) { config.headers = config.headers || {}; const token = $window.localStorage.getItem('tokenAPI'); if (token) { config.headers.Authorization = `Bearer ${token}`; } return config; }, // 收到401时可以自定义处理(比如跳登录页) responseError: function(rejection) { if (rejection.status === 401) { // 这里可以加令牌刷新逻辑,或者直接跳转到登录页 // $window.location.href = '/login'; } return $q.reject(rejection); } }; }]); // 注册拦截器到全局 app.config(['$httpProvider', function($httpProvider) { $httpProvider.interceptors.push('authInterceptor'); // 原来的全局默认头可以删掉了,拦截器会帮我们处理 // $httpProvider.defaults.headers.common['Authorization'] = 'Bearer '+localStorage.getItem('tokenAPI'); }]);
3. 检查第二个请求的URL是否合规
确认第二个请求的Global.url_api+'action=GET&table='+project+'_users'和第一个请求的域名、端口完全一致吗?如果project变量导致URL有变化(比如子域名不同),会触发新的CORS规则,得确保后端的CORS配置覆盖所有可能的请求来源。
验证方法
打开浏览器开发者工具(F12),切换到Network标签:
- 看第二个请求是否先发送了OPTIONS请求,检查它的响应状态码是不是200,响应头里的CORS配置是否正确。
- 再看实际的GET请求,查看Request Headers里有没有Authorization字段。
内容的提问来源于stack exchange,提问作者TotoNaBendo
相关产品推荐
相关产品推荐

