从代码中调用Laravel控制器,并将HTTP标头传递给它 [英] Call Laravel controller from code and pass HTTP headers to it

查看:63
本文介绍了从代码中调用Laravel控制器,并将HTTP标头传递给它的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

要调用控制器,我使用如下CURL请求:

To call a controller I use a CURL request like this:

curl -kX POST https://site/method  -H 'Authorization: Bearer ACCESS_TOKEN\
Content-Type:application/json' -d '
{
    "param1":"value 1",
    "param2":"value 2",
    "param3":"value 3"
}'

该路由调用UserController @ method.

The route calls UserController@method.

如何从Laravel代码(内部请求,不发送CURL)中做同样的事情?

How can I do the same from Laravel code (internal request, not sending CURL)?

我找到了使用这样的东西的建议

I've found an advice to use something like this

        $controller = app()->make($controllerName);
        $response = app()->call([$controller, 'method'], []);
        echo $response;

最后一个[]应该包含一些参数.但是如果这样,我将无法弄清数组在我的情况下的外观.

where the last [] should contain some parameters. But if this is the way, I cannot figure out how the array should look in my case.

P.S.请不要回答这是一种不好的做法",而不是给出如何实现我所需要的建议.

P.S. Please, don't answer "it's a bad practice" instead of giving an advice how to implement what I need.

推荐答案

这是我的解决方案(Laravel 5.4).受 https://stackoverflow.com/a/40366119/518704 的启发,但需要大量时间来深入研究代码才能找到如何通过我的 Authorization:Bearer 令牌

Here is my solution (Laravel 5.4). Inspired by https://stackoverflow.com/a/40366119/518704 but needed much time to dig into the code to find how to pass my Authorization: Bearer token

我需要这种方法来在没有运行JS代码的无浏览器套接字连接(Ratchet)中进行授权.因此,我不能使用Ratchet WebSocket,只能使用简单的套接字Ratchet IoServer .我的API控制器返回JSON,因此可以轻松地进一步处理响应.我主要需要这种方法来验证套接字连接,假设客户端在打开套接字时就知道访问令牌(登录时由REST获取).

I need this approach to authorize in a browser-less socket connection (Ratchet), where JS code is not running. So I could not use Ratchet WebSocket, only simple socket Ratchet IoServer. My API controller returns JSON so it's easy to work with the response further. I need this approach mainly to authenticate the socket connection assuming the client knows the access token when one opens the socket (got by REST on login).

首先,我需要使用测试中使用的特征

First of all I need to use a trait, used in Tests

下一步,在 onMessage 代码中,我假设使用访问令牌传递了JSON消息.为了简化这里,我不编写JSON有效性检查等.

Next in onMessage code I assume a JSON message is passed with the access token. To simplify here I don't write JSON validity check etc.

namespace App;

use Ratchet\ConnectionInterface;
use Askedio\LaravelRatchet\RatchetServer as RatchetServerBase;

class RatchetServer extends RatchetServerBase
{
...
    public function onMessage(ConnectionInterface $conn, $input)
    {
          $input = json_decode($input);
          $token = $input->token;


          // Some data (may be taken from JSON $input)
          $data = [
            "param1" => "value 1",
            "param2" => "value 2",
            "param3" => "value 3"
          ];

          // Prepare the server headers
          $server = ['HTTP_AUTHORIZATION' => 'Bearer ' . $token];

          // This way! If calling app() here, it reuses the same Auth::user() 
          $app = require __DIR__.'/../bootstrap/app.php';
          $kernel = $app->make(\Illuminate\Contracts\Http\Kernel::class);
          $response = $kernel->handle(
              $request = \Illuminate\Http\Request::create('/user', 'GET', $data, [], [], $server)
          );
          // ~ var_dump(Auth::id());
          $controllerResult = $response->getContent();
          $kernel->terminate($request, $response);

          // My controller hidden under /user route is an API one and returns JSON string
          echo $controllerResult;
    }
...
}

我以前的解决方案不起作用. Auth :: user()始终返回 首次登录的用户(app()似乎使用单例).所以我离开了 先前的代码仅供参考.

My previous solution didn't work. The Auth::user() always returned the first logged in user (app() seemed to use singleton). So I leave the previous code for reference purpose.

namespace App;

use Ratchet\ConnectionInterface;
use Askedio\LaravelRatchet\RatchetServer as RatchetServerBase;

class RatchetServer extends RatchetServerBase
{
    use \Illuminate\Foundation\Testing\Concerns\MakesHttpRequests;

...
    public function onMessage(ConnectionInterface $conn, $input)
    {
          $input = json_decode($input);
          $token = $input->token;

          $data = [
            "param1" => "value 1",
            "param2" => "value 2",
            "param3" => "value 3"
          ];

          // The 2 lines below can me moved to the __constructor method
          $this->baseUrl = request()->getSchemeAndHttpHost();
          $this->app     = app();

          // Prepare the server headers
          $server = ['HTTP_AUTHORIZATION' => 'Bearer ' . $token];

          // Call my controller by route (this seems to be internal call)
          $response = $this->call('GET','/method', $data, [], [], $server)->json();
    }
...
}

P.S.稍后我来这里时,只为给我自己一个便条.看不到可用的标头和正确的命名,我在$this->parameters ./vendor/symfony/http-foundation//ServerBag.php

P.S. Just a note for myself when I come here later. Too see available headers and proper naming I did a var_dump in for $this->parameters ./vendor/symfony/http-foundation//ServerBag.php

这篇关于从代码中调用Laravel控制器,并将HTTP标头传递给它的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆