laravel-graphql
laravel-graphql copied to clipboard
middleware_schema doesn't work
Hi, I think that middleware_schema parameter in config doesn't work. I created another schema "secret", to this point everything is working fine but code below doesn't. It seems that even if I will query secret schema, "default" middleware is take charge here instead of "secret" middlewares.
'middleware_schema' => [
'default' => ['auth'],
'secret' => ['api', 'auth:users_api']
],
Basically middleware will be used defined here:
'schema' => 'default',
Instead from 'middleware_schema'.
Tried to reproduce your issue, but it looks fine on my end.
Can you create an example project where this happens?
On Laravel 5.6, you need to add graphql to your middleware groups.
App\Http\Kernel.php Add the following to your $middlewareGroups array:
'graphql' => [ \App\Http\Middleware\EncryptCookies::class, \Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class, \Illuminate\Session\Middleware\StartSession::class, ],
Then in your graphql.php config file, update your middleware to look like the following:
'middleware' => [ 'graphql', 'auth' ],
Change any of the middleware_schema to whatever you would like.
middleware_schema not works on Lumen 5.6
@Bowens20832 Lumen does not have middlewareGroups
middleware defined in routeMiddleware can't be used in middleware_schema
@kevinvdburgt Could you take a look at this problem?
I think i got the middleware_schema implementaion to work in Lumen.
For everyone who is interested; I copied the GraphQLController into my Http/Controllers folder and tweaked it a bit. Now it looks like this:
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
class GraphQLController extends Controller
{
protected $schema;
public function __construct(Request $request)
{
$route = $request->route();
// Prevent schema middlewares to be applied to graphiql routes
$routeName = is_object($route) ? $route->getName() : null;
if (!is_null($routeName) && preg_match('/^graphql\.graphiql/', $routeName)) {
return;
}
$defaultSchema = config('graphql.schema');
if (is_array($route)) {
$this->schema = array_get($route, '2.graphql_schema', $defaultSchema);
} elseif (is_object($route)) {
$this->schema = $route->parameter('graphql_schema', $defaultSchema);
} else {
$this->schema = $defaultSchema;
}
$middleware = config('graphql.middleware_schema.' . $this->schema, null);
if ($middleware) {
if (is_array($middleware)) {
foreach ($middleware as $entry) {
$this->middleware($entry);
}
} else {
$this->middleware($middleware);
}
}
}
public function query(Request $request, $schema = null)
{
$isBatch = !$request->has('query');
$inputs = $request->all();
if (!$schema) {
$schema = $this->schema;
}
if (!$isBatch) {
$data = $this->executeQuery($schema, $inputs);
} else {
$data = [];
foreach ($inputs as $input) {
$data[] = $this->executeQuery($schema, $input);
}
}
$headers = config('graphql.headers', []);
$options = config('graphql.json_encoding_options', 0);
$errors = !$isBatch ? array_get($data, 'errors', []) : [];
$authorized = array_reduce($errors, function ($authorized, $error) {
return !$authorized || array_get($error, 'message') === 'Unauthorized' ? false : true;
}, true);
if (!$authorized) {
return response()->json($data, 403, $headers, $options);
}
return response()->json($data, 200, $headers, $options);
}
public function graphiql(Request $request, $schema = null)
{
$view = config('graphql.graphiql.view', 'graphql::graphiql');
return view($view, [
'schema' => $schema,
]);
}
protected function executeQuery($schema, $input)
{
$variablesInputName = config('graphql.variables_input_name', 'variables');
$query = array_get($input, 'query');
$variables = array_get($input, $variablesInputName);
if (is_string($variables)) {
$variables = json_decode($variables, true);
}
$operationName = array_get($input, 'operationName');
$context = $this->queryContext($query, $variables, $schema);
return app('graphql')->query($query, $variables, [
'context' => $context,
'schema' => $schema,
'operationName' => $operationName
]);
}
protected function queryContext($query, $variables, $schema)
{
try {
return app('auth')->user();
} catch (\Exception $e) {
return null;
}
}
}
The crucial parts are:
GraphQLController extends ControllerorBaseController- determine current schema in
__construct - go through all middleware entries if it es an array in end of
__construct - use the right schema in the
querymethod
if (!$schema) {
$schema = $this->schema;
}
Also you need the following config:
'controllers' => \App\Http\Controllers\GraphQLController::class.'@query',
It's really sad that this package is kind of dead. If that would not be the case, I would be happy to create a pull request.