来自deepseek:php禁止跨域请求
在PHP中,禁止API被跨域调用可以通过设置HTTP响应头来实现。跨域资源共享(CORS,Cross-Origin Resource Sharing)是一种机制,允许浏览器从不同域名的服务器请求资源。如果不希望API被跨域调用,可以通过以下方式限制。
1. 禁止所有跨域请求
通过设置Access-Control-Allow-Origin
响应头为null
或特定域名,可以限制跨域请求。
<?php
header('Content-Type: application/json');
// 禁止所有跨域请求
header('Access-Control-Allow-Origin: null');
// 或者只允许特定域名访问
// header('Access-Control-Allow-Origin: https://example.com');
// 示例API逻辑
echo json_encode(['message' => 'This API cannot be accessed from other domains.']);
?>
2. 完全禁用CORS
如果希望完全禁用CORS,可以设置以下响应头:
<?php
header('Content-Type: application/json');
// 禁用CORS
header('Access-Control-Allow-Origin: none');
header('Access-Control-Allow-Methods: none');
header('Access-Control-Allow-Headers: none');
// 示例API逻辑
echo json_encode(['message' => 'CORS is disabled for this API.']);
?>
3. 检查请求来源
通过检查$_SERVER['HTTP_ORIGIN']
,可以动态限制允许的域名。
<?php
header('Content-Type: application/json');
// 允许的域名列表
$allowedOrigins = [
'https://example.com',
'https://sub.example.com'
];
// 获取请求来源
$origin = $_SERVER['HTTP_ORIGIN'] ?? '';
// 检查请求来源是否在允许列表中
if (in_array($origin, $allowedOrigins)) {
header("Access-Control-Allow-Origin: $origin");
} else {
http_response_code(403); // Forbidden
echo json_encode(['error' => 'Cross-origin requests are not allowed.']);
exit;
}
// 示例API逻辑
echo json_encode(['message' => 'This API can only be accessed from specific domains.']);
?>
4. 限制HTTP方法
除了限制来源,还可以限制允许的HTTP方法(如只允许GET请求)。
<?php
header('Content-Type: application/json');
// 允许的HTTP方法
$allowedMethods = ['GET'];
// 获取请求方法
$method = $_SERVER['REQUEST_METHOD'];
// 检查请求方法是否允许
if (!in_array($method, $allowedMethods)) {
http_response_code(405); // Method Not Allowed
echo json_encode(['error' => 'This method is not allowed.']);
exit;
}
// 示例API逻辑
echo json_encode(['message' => 'This API only supports GET requests.']);
?>
5. 结合认证与授权
如果API需要认证,可以在禁止跨域请求的同时验证用户的身份和权限。
<?php
header('Content-Type: application/json');
// 禁止跨域请求
header('Access-Control-Allow-Origin: null');
// 检查认证
if (!isset($_SERVER['HTTP_AUTHORIZATION'])) {
http_response_code(401); // Unauthorized
echo json_encode(['error' => 'Authorization token is required.']);
exit;
}
$token = str_replace('Bearer ', '', $_SERVER['HTTP_AUTHORIZATION']);
// 验证Token(示例)
if ($token !== 'valid-token') {
http_response_code(403); // Forbidden
echo json_encode(['error' => 'Invalid token.']);
exit;
}
// 示例API逻辑
echo json_encode(['message' => 'This API is protected and cannot be accessed from other domains.']);
?>
6. 使用.htaccess
限制跨域请求
如果使用Apache服务器,可以通过.htaccess
文件限制跨域请求。
# 禁止所有跨域请求
<IfModule mod_headers.c>
Header set Access-Control-Allow-Origin "null"
</IfModule>
7. 使用Nginx配置限制跨域请求
如果使用Nginx服务器,可以通过配置文件限制跨域请求。
location /api {
if ($http_origin !~* "^https://example.com$") {
return 403;
}
add_header Access-Control-Allow-Origin $http_origin;
}
8. 注意事项
- 浏览器限制:CORS是浏览器端的限制,服务器端仍然可以接收跨域请求。
- 预检请求:对于复杂请求(如带有自定义头的请求),浏览器会先发送
OPTIONS
预检请求,服务器需要正确处理。 - 安全性:禁止跨域请求可以防止部分攻击,但应结合其他安全措施(如认证、输入验证)全面保护API。
9. 完整示例
以下是一个完整的PHP示例,禁止跨域请求并验证Token:
<?php
header('Content-Type: application/json');
// 禁止跨域请求
header('Access-Control-Allow-Origin: null');
// 检查认证
if (!isset($_SERVER['HTTP_AUTHORIZATION'])) {
http_response_code(401); // Unauthorized
echo json_encode(['error' => 'Authorization token is required.']);
exit;
}
$token = str_replace('Bearer ', '', $_SERVER['HTTP_AUTHORIZATION']);
// 验证Token(示例)
if ($token !== 'valid-token') {
http_response_code(403); // Forbidden
echo json_encode(['error' => 'Invalid token.']);
exit;
}
// 示例API逻辑
echo json_encode(['message' => 'This API is protected and cannot be accessed from other domains.']);
?>
通过以上方法,可以有效禁止API被跨域调用,提升API的安全性。
来自deepseek:php禁止跨域请求的更多相关文章
- Ajax_05之跨域请求
1.跨域请求: Cross Domain Request:跨域名的HTTP请求,浏览器从某个域名下的资源访问了另一域名下的另一资源(协议.域名或是端口号不同): ①浏览器允许跨域请求的情形: < ...
- NodeJ node.js Koa2 跨域请求
Koa2 .3 跨域请求 Haisen's 需求分析 (localhost:8080 = 前端 [请求] localhost:8081 = 服务器 ) 1.一个前台 一个服务器 前台 ...
- 跨域请求 & jsonp
0 什么是跨域请求 在一个域名下请求另外一个域名下的资源,就是跨域请求.example 1:比如:我当前的域名是http://che.pingan.com.我现在要去请求http://www.cnbl ...
- Nginx反向代理、CORS、JSONP等跨域请求解决方法总结
由于 Javascript 同源策略的存在使得一个源中加载来自其它源中资源的行为受到了限制.即会出现跨域请求禁止. 通俗一点说就是如果存在协议.域名.端口或者子域名不同服务端,或一者为IP地址,一者为 ...
- 【转载】Ajax JS 跨域请求
原文: 简单的ajax请求:http://blog.csdn.net/net_lover/article/details/5172509 复杂的ajax请求:http://blog.csdn.net/ ...
- ajax跨域请求解决方案 CORS和JSONP
什么是跨域: 只要协议.域名.端口有任何一个不同,都会被当成不同的域.而由于浏览器的同源策略(同源策略:域名.协议.端口均相同),浏览器之间要隔离不同域的内容,禁止互相操作,不能执行其他网站的js.所 ...
- [1.6W字] 浏览器跨域请求限制的详细原理分析&寻找一种最简单的方式实现XHR跨域(9种方法, 附大招可以纯前端实现跨域!)
Title/ 浏览器跨域(CrossOrigin)请求的原理, 以及解决方案详细指南 #flight.Archives011 序: 最近看到又有一波新的创作活动了, 官方给出的话题中有一个" ...
- [1.6W字]浏览器跨域请求的原理, 以及解决方法(可以纯前端实现) #flight.Archives011
Title/ 浏览器跨域(CrossOrigin)请求的原理, 以及解决方案详细指南 #flight.Archives011 序: 最近看到又有一波新的创作活动了, 官方给出的话题中有一个" ...
- 利用CORS实现跨域请求(转载)
跨域请求一直是网页编程中的一个难题,在过去,绝大多数人都倾向于使用JSONP来解决这一问题.不过现在,我们可以考虑一下W3C中一项新的特性--CORS(Cross-Origin Resource Sh ...
- 浅谈linux 下,利用Nginx服务器代理实现ajax跨域请求。
ajax跨域请求对于前端开发者几乎在任何一个项目中都会用到,众所周知,跨域请求有三种方式: jsonp; XHR2 代理: jsonp: 这种应该是开发中是使用的最多的,最常见的跨域请求方法,其实aj ...
随机推荐
- .NET 8 中的 ASP.NET Core 指标与 Grafana 仪表板入门
.NET 8 中的 ASP.NET Core 指标与 Grafana 仪表板入门 原文地址:https://devblogs.microsoft.com/dotnet/introducing-aspn ...
- Docker Install on Ubuntu
https://docs.docker.com/engine/install/ubuntu/ https://docs.docker.com/compose/install/linux/
- Windows下如何在当前目录下,打开cmd命令窗口
方法一: 在当前目录下,按下shift + 鼠标右键,会出现"在此处打开命令窗口"的字样,然后点击即可. 方法二: 在该文件夹上,按下shift + 鼠标右键,会出现"在 ...
- 关于Qt中的qss样式表需要注意的坑
关于QSS要注意的坑. qss源自css,相当于css的一个子集,主要支持的是css2标准,很多网上的css3的标准的写法在qss这里是不生效的,所以不要大惊小怪. qss也不是完全支持所有的css2 ...
- java EE进行Web开发时*.jsp页面的<%@显示“The superclass "javax.servlet.http.HttpServlet" was not found on the Java Build Path”错误,webcontent文件夹总是出现红x或者java源码出现The import javax.servlet cannot be resolved 的解决方法
我们在用Eclipse进行Java web开发时,可能会出现这样的错误:The superclass javax.servlet.http.HttpServlet was not found on t ...
- C Primer Plus 第6版 第三章 编程练习参考答案
编译环境VS Code+WSL GCC 源码在文末下载 /*第1题*************************/ #include<stdio.h> int main() { int ...
- Netty3 核心代码-copy
Netty Hello Word-copy 概述https://github.com/csy512889371/learndemo/netty/NettyHellonetty版本大致版本分为 ne ...
- linux内核 list_for_each_entry
1. linux内核中的list用法 在linus内核中,list一般这样使用: struct list_head { struct list_head *priv; struct list_head ...
- ABC237
ABC237 F 题目大意 求长度为 \(n\) 且最长上升子序列长度恰好为 \(3\) 的序列 \(a\) 的个数(\(1 \leq a_i \leq m\)). 解题思路 不难判断这道题是一道线性 ...
- 0425-FileRead字符输入流
package A10_IOStream; import java.awt.datatransfer.StringSelection; import java.io.IOException; impo ...