Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

bovisp's avatar
Level 10

axios returns a 419 response every time

I am using Laravel 5.5 and have been following along with the "Let's build a forum with Laravel and TDD" tutorials. I am in the middle of Lesson 32 where a Vue reply component is created. I have followed the tutorials to the letter and have made no modifications.

All of my non-AJAX requests have been fine. However, as soon as we use axios in this lesson, I'm getting a 419 response every time I try a patch request. I also get a 419 response with put, post and delete requests. I'm pretty comfortable with Vue and axios and have used them in tandem many times before with no issues.

When I get this 419 response, Laravel logs me out so it's an authentication issue for sure.

My relevant code:

reply.blade.php

<reply :attributes="{{ $reply }}" inline-template v-cloak>
    <div id="reply-{{ $reply->id }}" class="panel panel-default">
        <div class="panel-heading">
            <div class="level">
                <h5 class="flex">
                    <a href="{{ route('profile', $reply->owner) }}">
                        {{ $reply->owner->name }}
                    </a> said {{ $reply->created_at->diffForHumans() }}...
                </h5>

                <div>
                    <form method="POST" action="/replies/{{ $reply->id }}/favorites">
                        {{ csrf_field() }}

                        <button class="btn btn-default" type="submit" {{ $reply->isFavorited() ? 'disabled' : '' }}>
                            {{ $reply->favorites()->count() }}

                            {{ str_plural('Favorite', $reply->favorites_count) }}
                        </button>
                    </form>
                </div>
            </div>

        </div>

        <div class="panel-body">
            <div v-if="editing">
                <div class="form-group">
                    <textarea class="form-control" v-model="body"></textarea>
                </div>

                <button class="btn btn-xs btn-primary" @click="update">Update</button>
                <button class="btn btn-xs btn-link" @click="editing = false">Cancel</button>
            </div>

            <div v-else>
                {{ $reply->body }}
            </div>
        </div>

        @can('update', $reply)

        <div class="panel-footer level">
            <button class="btn btn-xs mr-1" @click="editing = true">Edit</button>

            <form method="POST" action="/replies/{{ $reply->id }}">
                {{ csrf_field() }}

                {{ method_field('DELETE')}}
 
                <button type="submit" class="btn btn-danger btn-xs">Delete</button>
            </form>
        </div>

    @endcan
    
    </div>
</reply>

Reply.vue

<script>
export default {
  props: ["attributes"],

  data() {
    return {
      editing: false,
      body: this.attributes.body
    };
  },

  methods: {
    update() {
      axios.patch("/replies/" + this.attributes.id, {
        body: this.body
      });

      this.editing = false;
    }
  }
};
</script>

routes/web.php

<?php

Auth::routes();

Route::get('/threads', 'ThreadsController@index');
Route::get('/threads/create', 'ThreadsController@create');
Route::post('/threads', 'ThreadsController@store');
Route::get('/threads/{channel}/{thread}', 'ThreadsController@show');
Route::delete('/threads/{channel}/{thread}', 'ThreadsController@destroy');
Route::get('/threads/{channel}', 'ThreadsController@index');

Route::post('/threads/{channel}/{thread}/replies', 'RepliesController@store');
Route::patch('/replies/{reply}', 'RepliesController@update');
Route::delete('/replies/{reply}', 'RepliesController@destroy');

Route::post('/replies/{reply}/favorites', 'FavoritesController@store');

Route::get('/profiles/{user}', 'ProfilesController@show')->name('profile');

Route::get('/home', 'HomeController@index')->name('home');

RepliesController

<?php

namespace App\Http\Controllers;

use App\Reply;
use App\Thread;
use Illuminate\Http\Request;

class RepliesController extends Controller
{
    public function __construct()
    {
        $this->middleware('auth');
    }

    /**
     * Store a newly created resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\Response
     */
    public function store($channelId, Thread $thread)
    {
        request()->validate([
            'body' => 'required'
        ]);

        $thread->addReply([
            'body' => request('body'),
            'user_id' => auth()->id()
        ]);

        return back()
            ->with('flash', 'Reply successfully created');
    }

    /**
     * Update the specified resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \App\Reply  $reply
     * @return \Illuminate\Http\Response
     */
    public function update(Request $request, Reply $reply)
    {
        $this->authorize('update', $reply);

        $reply->update(request(['body']));
    }

    /**
     * Remove the specified resource from storage.
     *
     * @param  \App\Reply  $reply
     * @return \Illuminate\Http\Response
     */
    public function destroy(Reply $reply)
    {
        $this->authorize('update', $reply);

        $reply->delete();

        return back();
    }
}

app/Policies/ReplyPolicy.php

<?php

namespace App\Policies;

use App\User;
use App\Reply;
use Illuminate\Auth\Access\HandlesAuthorization;

class ReplyPolicy
{
    use HandlesAuthorization;

    /**
     * Determine whether the user can update the reply.
     *
     * @param  \App\User  $user
     * @param  \App\Reply  $reply
     * @return mixed
     */
    public function update(User $user, Reply $reply)
    {
        return $reply->user_id == $user->id;
    }
}

Interestingly, when I dd(auth()->user()) in the constructor function of RepliesContoller when I issue the AJAX patch request:

RepliesController.php

...

public function __construct()
{
    dd(auth()->user());

    $this->middleware('auth');
}

it returns null and auth()->guest() returns true. If I dd(auth()->user()) on a non AJAX request or in the constructor of TheadsController, it returns the user.

Help!

0 likes
0 replies

Please or to participate in this conversation.