AngularJS 和 Laravel - CORS

Posted

技术标签:

【中文标题】AngularJS 和 Laravel - CORS【英文标题】:AngularJS and Laravel - CORS 【发布时间】:2015-04-12 10:31:09 【问题描述】:

我有以下设置: 前端的 AngularJS 向 Laravel API 发出 $http 请求。 例如,在开始时 mainCtrl 请求 Laravel 中的会话是否存在,如果存在,他将用户登录到应用程序。 我已经用 Postman 测试了 API,它运行良好。

我正在使用 Laravel 5

我发送这样的 JSON


      "user":"user",
      "password":"password"

API 会检查它是否有效,如果有效,则返回访问令牌。 它将令牌和用户 ID 写入 laravel 会话。

使用 rout /checkLogin 检查是否存在具有有效令牌的会话。这也适用于 Postman。

这里有两个来自 laravel 后端的 login 和 checkLogin 函数:

public function login()
       $user = User::where('email', '=', Input::get('login'))->first();
     if($user ==  null)
         $user = User::where('login', '=', Input::get('login'))->first();
         if($user != null)
             if($user->password==sha1(Input::get('password')))
            $token = new Token;
            $token->userid = $user->id;
            $token->token=self::getGUID();
            Session::put('user_id', $user->id);
            Session::put('user_token', $token->token);
            $token->save();
                        return $token->token;
               else
                     return "Wrong username or password";
          else
            return "Wrong username or password";
    

  public function checkLogin()
      $token =null;
      if(Session::has('user_token'))
          $token = Session::get('user_token');
      
      if($token ==  null)
          $token = Input::get('token');
      
      if($token != null)
          $test = Token::where('token', '=', $token)->where('userid', '=', Session::get('user_id'))->first();
          return User::where('id', '=', $test->userid)->first();
      
      return "no session";
  

我所知道的是创建一些 Angular 函数来使其真正发挥作用。 当我打开我的网站时,它应该检查用户是否已登录。它实际上会触发登录中的 get 函数。

example.factory('Login', function($http) 
        return 
                get : function() 
                        return $http(
                            method: 'GET',
                            url: 'http://api.example.com/checkLogin',
                            headers:  'Content-Type' : 'application/json' 
                        );
                ,

                save : function(loginData) 
                        return $http(
                                method: 'POST',
                                url: 'http://api.example.com/login',
                                headers:  'Content-Type' : 'application/json' ,
                                data: loginData
                        );
                
        

);

它似乎也可以正常工作。在我的控制台中,我看到“没有会话”。如果我没有登录应该没问题。 所以我现在尝试登录。我从上面从登录运行保存功能。将我的数据放在一起:

$scope.logmein = function () 
    loginData = 
                        'login' : $scope.login,
                        'password' : $scope.password
                ;
    Login.save(loginData)
                        .success(function(data) 
                            console.log(data);
                                Login.get()
                                        .success(function(getData) 
                                            console.log(getData);
                                            if(data==="no session")
                                                $scope.loggedin=false;
                                            
                                            else
                                                $scope.loggedin=true;
                                            
                                        );

                        )
                        .error(function(data) 
                                console.log(data);
                        );
                    

当我点击提交时,我在控制台中得到了预期的令牌。现在一切都应该好了。为了更新我的网站,我再次运行 checkLogin 功能。它现在应该把我的会话还给我,但它却说没有会话。当我登录时,会话应该放在一起。 我已经尝试了很多小时来修复这个问题,但很多时候它给了我一个 CORS 错误,或者当没有出现 CORS 错误时,它只是按照我刚刚解释的方式进行。

我希望你们当中有人能找出原因。

【问题讨论】:

只是一个注释...headers: 'Content-Type' : 'application/json' 对 GET 请求没有意义。您不是 发送 application/json 到服务器,而是从服务器接收它。 哦,对了,对不起,是我的错误。可悲的是它没有解决问题 【参考方案1】:

您需要在响应标头中设置“Access-Control-Allow-Origin”和“Access-Control-Allow-Methods”:

<?php
 header('Access-Control-Allow-Origin: *');
 header('Access-Control-Allow-Methods: POST, GET, OPTIONS');
?>

编辑

在 lavarel 中可以在所有响应中设置标头,在此 gist https://gist.github.com/eweap/1df3b1662a500857133a 中找到以下代码:

<?php namespace App\Http\Middleware;
use Closure;

use Illuminate\Contracts\Routing\Middleware;
use Illuminate\Http\Response;

class CORS implements Middleware 

 /**
  * Handle an incoming request.
  *
  * @param \Illuminate\Http\Request $request
  * @param \Closure $next
  * @return mixed
  */
 public function handle($request, Closure $next)
 
  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');
 

您需要在 Kernel.php 中设置此中间件

【讨论】:

我需要在哪里指定它?我已经安装了 barryvdh/laravel-cors,因为我认为可能存在 cors 问题。 你能试试 return response()->header('Access-Control-Allow-Origin', '*')->header('Access-Control-Allow-Methods', 'POST , 获取, 选项');结束你的方法 我还是遇到了同样的问题。我像预期的那样取回了一个令牌,但是当询问什么令牌会话得到它时,它告诉我我的会话中没有令牌。为了澄清新令牌已写入我的数据库,但是当我触发新的 checkLogin 请求时,它说我的会话中没有令牌。 我刚刚注意到我在 Firefox 中只取回了一个令牌。在 Chrome 中它告诉我“XMLHttpRequest 无法加载。没有'Access-Control-Allow-Origin'... 嗨 sebi55 我更新了我的答案,你在 Chrome 中得到的原因是标题设置不正确。

以上是关于AngularJS 和 Laravel - CORS的主要内容,如果未能解决你的问题,请参考以下文章

Laravel 4 和 AngularJS - 使用路由清理 URL

AngularJS 和 Laravel - CORS

使用 IIS、AngularJS 和 Laravel 删除 MethodNotAllowedHttpException

使用 Laravel 5.3 和 AngularJS 1.5 的路线行为不端

使用 Laravel、JWT 和 Angularjs 批处理令牌

AngularJS 和 Laravel Foreach