vendredi 30 juin 2017

Larave: CORS is working on all routes controller@method except for one route

I have Handled CROS in my Laravel Application for a certain resource

Route::resource('question', 'QuestionController');

when I added a new route within the same Route Group it doesn't work, for instance, this is the new route I wanted to add

Route::get('question/{question}/reply', 'QuestionController@getReply')->name('question.reply');

when I connect to this endpoint it gives me this: what I get when I request anything from the above endpoint

another wired thing is: when I rename the method to something that is from the resource defaule methods like show for instance, it works!

so If I renamed the routes to

Route::get('question/{question}/reply', 'QuestionController@show')->name('question.reply');

it works like a charm, why is that !!!!!!

Here is my QuestionController

    <?php

namespace App\Http\Controllers;

use App\Http\Controllers\elfehres\transformers\ReplyTransformer;
use Illuminate\Http\Request;
use App\Http\Controllers\elfehres\transformers\QuestionTransformer;
use App\Http\Controllers\elfehres\transformers\TagTransformer;
use App\Question;


//TODO handle duplicate entries
//TODO copy everything related to the index function from refereneController into QuestionController

class QuestionController extends ApiController
{

    protected $questionTransformer;
    protected $morphClass = 'replies';

    /**
     * ReferenceController constructor.
     */
    public function __construct()
    {
        $this->questionTransformer = resolve(QuestionTransformer::class);
        $this->middleware('jwt.auth', ['except' => ['index','show','getReply']]);
    }

    /**
     * Display a listing of the resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function index()
    {
        //TODO handle user transformation outside the question transformer, it should be handled here with tags
        $limit = (request('limit')) ? (request('limit') < 20) ? request('limit') : 20 :3;
        $questions = Question::paginate($limit)->load('user','tags.user')->map(function ($question) {
            $question['summary'] =   $question->replies()->repliesSummary()->toArray();
            $transformedRelatedQuestionObjectData = $this->transformRawQuestion([
                'tags'      =>  $question['tags']->toArray(),
            ]);

            unset($question['tags']);

            $transformedReference= $this->questionTransformer->transform($question, $transformedRelatedQuestionObjectData);

            return $transformedReference;
        });

        return response($questions); //TODO :: handle transforming the response before sending it
    }

    /**
     * Show the form for creating a new resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function create()
    {
        //
    }

    /**
     * Store a newly created resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\Response
     */
    public function store(Request $request)
    {
        //
    }

    public function getReply($id)
    {
        $question = Question::find($id);

        if(! $question){
            return $this->respondNotFound("Question is not found");
        }

        $question['summary'] =   $question->replies()->repliesSummary()->toArray();
        $fullRawReferenceObject = $question->load('replies.reply', 'replies.user')->toArray();

        $transformedRelatedReferenceObjectData = $this->transformRawReferenceObject([
            'tags'  =>  [],
            'replies'   =>  $fullRawReferenceObject['replies']
        ]);

        unset( $fullRawReferenceObject['replies']);

        $transformedReference= $this->questionTransformer->transform($fullRawReferenceObject, $transformedRelatedReferenceObjectData);

        return $this->respond($transformedReference);

    }
    /**
     * Display the specified resource.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function show($id)
    {
        //TODO return replies grouped by reply type instead of implementing it in the frontend, handle it here.
        //TODO handle show method
        //hanlde returning only the quesiton, and don't return the replies, until the user asks for it

        $question = Question::find($id);

        if(! $question){
            return $this->respondNotFound("Question is not found");
        }

        $question['summary'] =   $question->replies()->repliesSummary()->toArray();

        $fullRawReferenceObject = $question->load('user','tags.user')->toArray();

        $transformedRelatedReferenceObjectData = $this->transformRawReferenceObject([
            'tags'      =>  $fullRawReferenceObject['tags'],
            'replies'   =>  []//$fullRawReferenceObject['replies']
        ]);


        unset(  $fullRawReferenceObject['tags']
          //  $fullRawReferenceObject['replies']
        );

        $transformedReference= $this->questionTransformer->transform($fullRawReferenceObject, $transformedRelatedReferenceObjectData);

        return $this->respond($transformedReference);

    }

    public function transformRawReferenceObject($relatedReferenceObjectsTobeTransformedForSingleReferenceDisplay)
    {
        return array_merge( ['tags'      =>     $this->transformTagsForReference($relatedReferenceObjectsTobeTransformedForSingleReferenceDisplay['tags'])],
                            ['replies'   =>     $this->transformRepliesForQuestion($relatedReferenceObjectsTobeTransformedForSingleReferenceDisplay['replies'])]
        );
    }

    public function transformRawQuestion($relatedReferenceObjectsTobeTransformedForSingleReferenceDisplay)
    {
        return array_merge( ['tags'      =>     $this->transformTagsForReference($relatedReferenceObjectsTobeTransformedForSingleReferenceDisplay['tags'])] );
    }

    public function transformRepliesForQuestion($replies)
    {
        return array_map([$this, 'transformReplyForQuestion'], $replies);
    }

    public function transformReplyForQuestion($reply){

        $replyTransformer = resolve(ReplyTransformer::class);
        $transformedReply = $replyTransformer->transform($reply);

        unset($replyTransformer);
        return $transformedReply;
    }

    public function transformTagsForReference(array $tags)
    {
        $tagTransformer     =   resolve(TagTransformer::class);
        $transformedTags    =   $tagTransformer->transformTagsForPatchReferenceDisplay($tags);

        unset($tagTransformer);
        return $transformedTags;
    }

    /**
     * Show the form for editing the specified resource.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function edit($id)
    {
        //
    }

    /**
     * Update the specified resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function update(Request $request, $id)
    {
        //
    }

    /**
     * Remove the specified resource from storage.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function destroy($id)
    {
        //
    }
}

This is my api.php

    <?php

use Illuminate\Http\Request;

/*
|--------------------------------------------------------------------------
| API Routes
|--------------------------------------------------------------------------
|
| Here is where you can register API routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| is assigned the "api" middleware group. Enjoy building your API!
|
*/
//
//Route::middleware('auth:api')->get('/user', function (Request $request) {
//    return $request->user();
//});



Route::post('authenticate', 'AuthenticateController@authenticate');
Route::get('refresh', 'AuthenticateController@refresh');

Route::middleware('cors')->get('question/{question}/reply', 'QuestionController@getReply')->name('question.reply'); //TODO handle CORS Here

Route::resource('reference', 'ReferenceController');
Route::resource('question', 'QuestionController');
Route::resource('tag', 'TagController');
Route::resource('book', 'BookReplyController');
Route::resource('video', 'VideoReplyController');
Route::resource('sci_paper', 'SPaperController');

Here is my cors middleware

<?php

namespace App\Http\Middleware;

use Closure;

class Cors {
    public function handle($request, Closure $next)
    {
       $response = $next($request)
       ->header('Access-Control-Allow-Origin', '*')
        ->header('Access-Control-Allow-Methods', '*')
        ->header('Access-Control-Allow-Headers', 'Origin, Content-Type, Accept, Authorization, X-Request-With')
        ->header('Access-Control-Allow-Credentials', 'true');

        return $response;

    }
}

here is my app/Http/Kernal.php

<?php

namespace App\Http;

use Illuminate\Foundation\Http\Kernel as HttpKernel;

class Kernel extends HttpKernel
{
    /**
     * The application's global HTTP middleware stack.
     *
     * These middleware are run during every request to your application.
     *
     * @var array
     */
    protected $middleware = [
        \Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode::class,
        \Illuminate\Foundation\Http\Middleware\ValidatePostSize::class,
        \App\Http\Middleware\TrimStrings::class,
        \Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class,
    ];

    /**
     * The application's route middleware groups.
     *
     * @var array
     */
    protected $middlewareGroups = [
        'web' => [
            \App\Http\Middleware\EncryptCookies::class,
            \Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
            \Illuminate\Session\Middleware\StartSession::class,
            // \Illuminate\Session\Middleware\AuthenticateSession::class,
            \Illuminate\View\Middleware\ShareErrorsFromSession::class,
//            \App\Http\Middleware\VerifyCsrfToken::class,
            \Illuminate\Routing\Middleware\SubstituteBindings::class,
        ],

        'api' => [
            'throttle:60,1',
            'bindings',
            'cors' => \App\Http\Middleware\Cors::class,
        ],
    ];

    /**
     * The application's route middleware.
     *
     * These middleware may be assigned to groups or used individually.
     *
     * @var array
     */
    protected $routeMiddleware = [
        'auth' => \Illuminate\Auth\Middleware\Authenticate::class,
        'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
        'bindings' => \Illuminate\Routing\Middleware\SubstituteBindings::class,
        'can' => \Illuminate\Auth\Middleware\Authorize::class,
        'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
        'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
        'jwt.auth' => 'Tymon\JWTAuth\Middleware\GetUserFromToken',
        'jwt.refresh' => 'Tymon\JWTAuth\Middleware\RefreshToken',
        'cors' => \App\Http\Middleware\Cors::class,

    ];
}

here is the

php artisan route:list 

result

    +--------+-----------+-----------------------------------+-------------------+----------------------------------------------------------+--------------+
| Domain | Method    | URI                               | Name              | Action                                                   | Middleware   |
+--------+-----------+-----------------------------------+-------------------+----------------------------------------------------------+--------------+
|        | GET|HEAD  | /                                 |                   | Closure                                                  | web          |
|        | POST      | api/v2/authenticate               |                   | App\Http\Controllers\AuthenticateController@authenticate | api          |
|        | POST      | api/v2/book                       | book.store        | App\Http\Controllers\BookReplyController@store           | api          |
|        | GET|HEAD  | api/v2/book                       | book.index        | App\Http\Controllers\BookReplyController@index           | api          |
|        | GET|HEAD  | api/v2/book/create                | book.create       | App\Http\Controllers\BookReplyController@create          | api          |
|        | DELETE    | api/v2/book/{book}                | book.destroy      | App\Http\Controllers\BookReplyController@destroy         | api          |
|        | PUT|PATCH | api/v2/book/{book}                | book.update       | App\Http\Controllers\BookReplyController@update          | api          |
|        | GET|HEAD  | api/v2/book/{book}                | book.show         | App\Http\Controllers\BookReplyController@show            | api          |
|        | GET|HEAD  | api/v2/book/{book}/edit           | book.edit         | App\Http\Controllers\BookReplyController@edit            | api          |
|        | GET|HEAD  | api/v2/question                   | question.index    | App\Http\Controllers\QuestionController@index            | api          |
|        | POST      | api/v2/question                   | question.store    | App\Http\Controllers\QuestionController@store            | api,jwt.auth |
|        | GET|HEAD  | api/v2/question/create            | question.create   | App\Http\Controllers\QuestionController@create           | api,jwt.auth |
|        | DELETE    | api/v2/question/{question}        | question.destroy  | App\Http\Controllers\QuestionController@destroy          | api,jwt.auth |
|        | GET|HEAD  | api/v2/question/{question}        | question.show     | App\Http\Controllers\QuestionController@show             | api          |
|        | PUT|PATCH | api/v2/question/{question}        | question.update   | App\Http\Controllers\QuestionController@update           | api,jwt.auth |
|        | GET|HEAD  | api/v2/question/{question}/edit   | question.edit     | App\Http\Controllers\QuestionController@edit             | api,jwt.auth |
|        | GET|HEAD  | api/v2/question/{question}/reply  | question.reply    | App\Http\Controllers\QuestionController@getReply         | api,cors     |
|        | POST      | api/v2/reference                  | reference.store   | App\Http\Controllers\ReferenceController@store           | api,jwt.auth |
|        | GET|HEAD  | api/v2/reference                  | reference.index   | App\Http\Controllers\ReferenceController@index           | api          |
|        | GET|HEAD  | api/v2/reference/create           | reference.create  | App\Http\Controllers\ReferenceController@create          | api,jwt.auth |
|        | PUT|PATCH | api/v2/reference/{reference}      | reference.update  | App\Http\Controllers\ReferenceController@update          | api,jwt.auth |
|        | GET|HEAD  | api/v2/reference/{reference}      | reference.show    | App\Http\Controllers\ReferenceController@show            | api          |
|        | DELETE    | api/v2/reference/{reference}      | reference.destroy | App\Http\Controllers\ReferenceController@destroy         | api,jwt.auth |
|        | GET|HEAD  | api/v2/reference/{reference}/edit | reference.edit    | App\Http\Controllers\ReferenceController@edit            | api,jwt.auth |
|        | GET|HEAD  | api/v2/refresh                    |                   | App\Http\Controllers\AuthenticateController@refresh      | api          |
|        | POST      | api/v2/sci_paper                  | sci_paper.store   | App\Http\Controllers\SPaperController@store              | api          |
|        | GET|HEAD  | api/v2/sci_paper                  | sci_paper.index   | App\Http\Controllers\SPaperController@index              | api          |
|        | GET|HEAD  | api/v2/sci_paper/create           | sci_paper.create  | App\Http\Controllers\SPaperController@create             | api          |
|        | PUT|PATCH | api/v2/sci_paper/{sci_paper}      | sci_paper.update  | App\Http\Controllers\SPaperController@update             | api          |
|        | DELETE    | api/v2/sci_paper/{sci_paper}      | sci_paper.destroy | App\Http\Controllers\SPaperController@destroy            | api          |
|        | GET|HEAD  | api/v2/sci_paper/{sci_paper}      | sci_paper.show    | App\Http\Controllers\SPaperController@show               | api          |
|        | GET|HEAD  | api/v2/sci_paper/{sci_paper}/edit | sci_paper.edit    | App\Http\Controllers\SPaperController@edit               | api          |
|        | POST      | api/v2/tag                        | tag.store         | App\Http\Controllers\TagController@store                 | api          |
|        | GET|HEAD  | api/v2/tag                        | tag.index         | App\Http\Controllers\TagController@index                 | api          |
|        | GET|HEAD  | api/v2/tag/create                 | tag.create        | App\Http\Controllers\TagController@create                | api          |
|        | DELETE    | api/v2/tag/{tag}                  | tag.destroy       | App\Http\Controllers\TagController@destroy               | api          |
|        | GET|HEAD  | api/v2/tag/{tag}                  | tag.show          | App\Http\Controllers\TagController@show                  | api          |
|        | PUT|PATCH | api/v2/tag/{tag}                  | tag.update        | App\Http\Controllers\TagController@update                | api          |
|        | GET|HEAD  | api/v2/tag/{tag}/edit             | tag.edit          | App\Http\Controllers\TagController@edit                  | api          |
|        | POST      | api/v2/video                      | video.store       | App\Http\Controllers\VideoReplyController@store          | api          |
|        | GET|HEAD  | api/v2/video                      | video.index       | App\Http\Controllers\VideoReplyController@index          | api          |
|        | GET|HEAD  | api/v2/video/create               | video.create      | App\Http\Controllers\VideoReplyController@create         | api          |
|        | PUT|PATCH | api/v2/video/{video}              | video.update      | App\Http\Controllers\VideoReplyController@update         | api          |
|        | DELETE    | api/v2/video/{video}              | video.destroy     | App\Http\Controllers\VideoReplyController@destroy        | api          |
|        | GET|HEAD  | api/v2/video/{video}              | video.show        | App\Http\Controllers\VideoReplyController@show           | api          |
|        | GET|HEAD  | api/v2/video/{video}/edit         | video.edit        | App\Http\Controllers\VideoReplyController@edit           | api          |
+--------+-----------+-----------------------------------+-------------------+----------------------------------------------------------+--------------+

so I believe that it should be working properly, please if someone can tell me what it works only for the

Route::resource('question','QuestionController')

I would be really glad sorry for the long details



via Chebli Mohamed

Aucun commentaire:

Enregistrer un commentaire