如标题:我想在ajax的header头增加自定义Token进行跨域api认证并调用,api使用laravel5编写,如何实现?

首先,了解下CORS简单请求和复杂请求。

     -- CORS简单请求 --

链接:https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Access_control_CORS

1、ajax跨域,使用CORS方式  --  (ajax跨域会自动提交origin字段,用户不可伪造)

2、HTML的js:

</body>
<script type="text/javascript">
$(function(){
$(document).on("click", ".btn-all2", function(){
$.ajax({
url:"http://t-local.*****.com/wechat/auth/up?call_back=http%3A%2F%2Ftest.*****.com%2Findex.php%3Fg%3DWeixin%26m%3DWeixin%26a%3Dindex",
dataType:"json",
type:"get", //origin字段不允许自定义伪造;跨域请求浏览器自动带上origin // 允许携带cookie凭证
xhrFields: { withCredentials: true },
// 允许跨域
crossDomain: true, success:function(data){
console.log('success');
console.log(JSON.stringify(data));
},
error: function(data){
console.log('error');
console.log(JSON.stringify(data));
}
})
})
})
</script>
</html>

laravel5后台ajax请求过滤中间件: -- laravel 5 用来处理【简单请求】或者【复杂请求的第二次请求】

//跨域XML请求,会自动带上http_origin字段
public function handle( $request, Closure $next )
{
$origin = isset($_SERVER['HTTP_ORIGIN'])? $_SERVER['HTTP_ORIGIN'] : '';
$allow_origin = Config::get('app.allow_origin');
$allow_origin_dynamic = Config::get('app.allow_origin_dynamic'); $allowOrigin = false;
if ( in_array( $origin, $allow_origin ))
{
$allowOrigin = true;
} else {
foreach ( $allow_origin_dynamic as $item )
{
if ( strpos( $origin, $item ) !== false )
{
$allowOrigin = true;
break;
}
}
}
if ( $allowOrigin )
{
header('Access-Control-Allow-Origin: '.$origin);
header('Access-Control-Allow-Methods:POST,GET,OPTIONS,PUT,DELETE');
header('Access-Control-Allow-Headers:x-requested-with,content-type');
header('Access-Control-Allow-Credentials:true');
}
return $next($request); }

    ------  CORS复杂请求   --------

链接:https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Access_control_CORS

复杂请求 =【预请求 + 简单请求】;

一次XMLHttpRequest会发送两次请求,一次options、一次自定义的请求

那么在TP5中,我们可以使用行为扩展处理ajax|axios 带自定义头token的CORS请求,在laravel5中怎样解决呢?

laravel5 解决方案:

1、域名一:local.domian.com前端发起跨域ajax请求:访问laravel5的t-local.domian.com域名二

<script type="text/javascript">
$(function(){
$(document).on("click", ".btn-all2", function(){
$.ajax({
url:"http://t-local.****.com/api/wechat/auth/up?call_back=http%3A%2F%2Ftest.****.com%2Findex.php%3Fg%3DWeixin%26m%3DWeixin%26a%3Dindex",
dataType:"json",
type:"get", //origin字段不允许自定义伪造;跨域请求浏览器自动带上origin //自定义请求头认证token
headers: { 'token' : "2211zxz" }, // 允许携带cookie凭证
xhrFields: { withCredentials: true },
// 允许跨域
crossDomain: true, success:function(data){
console.log('success');
console.log(JSON.stringify(data));
},
error: function(data){
console.log('error');
console.log(JSON.stringify(data));
}
})
})
})
</script>

2、在laravel的route/api.php路由文件,增加以下路由规则:

/**
* laravel5发送复杂cors请求,类似jwt、自定义请求头token等,会先发送预请求options
* @param : 预请求options的【Access-Control-Allow-Origin:】绝对不可以设置成*,否则报错
* @return : code 200
* date: 2019年10月30日下午2:29:50
* author: xzz
*/
Route::options('/{all}',function () {
//file_put_contents(storage_path('logs/SERVER_Header.txt'), 'array = ' . var_export(request()->header(), true) . PHP_EOL, FILE_APPEND);
//file_put_contents(storage_path('logs/SERVER_Header.txt'), 'string' . var_export(request()->header('ORIGIN'), true) . PHP_EOL, FILE_APPEND);
$origin = request()->header('ORIGIN')??request()->header('HTTP_ORIGIN'); header("Access-Control-Allow-Origin: $origin");
header("Access-Control-Allow-Credentials: true");
header('Access-Control-Allow-Methods: POST, GET, OPTIONS, PUT, DELETE');
header('Access-Control-Allow-Headers: Origin, Access-Control-Request-Headers, SERVER_NAME, Access-Control-Allow-Headers, cache-control, token, X-Requested-With, Content-Type, Accept, Connection, User-Agent');
})->where(['all' => '([a-zA-Z0-9-]|/)*']);

3、返回前端F12打开,发现options请求已通过:

4、在创建一个【ajax简单请求】验证中间件(如果是简单请求,上面都可以省略),App\Middleware\AjaxHeader.php,kernel.php注册在api里面

<?php

namespace App\Http\Middleware;

use Closure;
use Illuminate\Support\Facades\{Config}; class AjaxHeader
{
/**
* @param $request
* @param Closure $next
* @return mixed
*/
public function handle( $request, Closure $next )
{
file_put_contents(storage_path('logs/1.txt'), var_export($_SERVER, true) . PHP_EOL, FILE_APPEND);
file_put_contents(storage_path('logs/SERVER_HeaderReal.txt'), 'array = ' . var_export(request()->header(), true) . PHP_EOL, FILE_APPEND);
file_put_contents(storage_path('logs/SERVER_HeaderReal.txt'), 'string' . var_export(request()->header('ORIGIN'), true) . PHP_EOL, FILE_APPEND); $origin = isset($_SERVER['HTTP_ORIGIN'])? $_SERVER['HTTP_ORIGIN'] : '';
$allow_origin = Config::get('app.allow_origin');
$allow_origin_dynamic = Config::get('app.allow_origin_dynamic'); $allowOrigin = false;
if ( in_array( $origin, $allow_origin ))
{
$allowOrigin = true;
} else {
foreach ( $allow_origin_dynamic as $item )
{
if ( strpos( $origin, $item ) !== false )
{
$allowOrigin = true;
break;
}
}
}
if ( $allowOrigin )
{
header('Access-Control-Allow-Origin: '.$origin);
header('Access-Control-Allow-Methods:POST,GET,OPTIONS,PUT,DELETE');
header('Access-Control-Allow-Headers:x-requested-with,content-type,token');
header('Access-Control-Allow-Credentials:true');
}
return $next($request);
/* return $next($request)-> header('Access-Control-Allow-Origin', '*')
-> header('Access-Control-Allow-Methods', 'POST,GET,OPTIONS,PUT,DELETE')
-> header('Access-Control-Allow-Headers', 'Content-Type,Accept,Authorization,X-Requested-With');*/
}
}

5、上面注册的api中间件绑定到t-local的api/wechat/xxx路由上,从local域名发起访问t-local域名,发现get请求也成功返回了json数据

返回的json数据:数据正确返回了,至于返回的是什么,这已经不重要了,不是吗?!!

6、至此,则完成了laravel5 处理ajax 携带自定义header头Token,并发起的跨域CORS的复杂请求。

最新文章

  1. MongoDB聚合运算之mapReduce函数的使用(11)
  2. .NET静态变量与静态方法并发的问题
  3. 【转】apue《UNIX环境高级编程第三版》第一章答案详解
  4. hdu 4267 树形DP
  5. iOS本地动态验证码生成-b
  6. Djang DJANGO_SETTINGS_MODULE
  7. js文件缓存之版本管理
  8. LINUX系统GIT使用教程
  9. WebService应用一例,带有安全验证
  10. CC++初学者编程教程(15) 基于cocos2dx的安卓打包环境
  11. 阿里P8分享:关于做事方式与做事态度
  12. go编程基础
  13. HTML5中将video设置为背景的方法
  14. 五子棋的斜对角方向上的规则 -- java编程(简单粗暴版)
  15. 获取服务器时间js代码
  16. JWT学习小结
  17. 大数据之hiveSQL
  18. 依据Axis2官网的高速入门英文文档总结
  19. 解决双系统(Window10+Ubuntu16.10)下ubuntu安装git时提示软件包git没有可安装候选问题
  20. 基于sql service会话共享,实现SSO

热门文章

  1. 学校老师没重点讲的C语言
  2. python3.5如何安装statsmodels包?
  3. Appium-desktop元素定位
  4. postgresql9.5编译安装体验
  5. HTTP状态码面试必知
  6. 性能测试基础---SQL基础
  7. graylog-日志收集
  8. wordpress调用置顶文章sticky_posts的三种方法
  9. Boring counting HDU - 3518 (后缀自动机)
  10. vmvare ESXi使用