TomBaine
TomBaine

Reputation: 773

Laravel reports a 400 (Bad request; Token not provided) in my VueJS + JWT-driven system

When I submit a form from a Vue component via axios, a 400 Bad request is returned. Generating the token (through logging in/registering) works fine and the request headers show a token present in the Authorization header. I've checked the order of Exception reporting in 'handler.php' and the JWTException being triggered is the last Exception type checked. I read that my .htaccess might be incorrectly configured, but that isn't the case.

I'm working on a Windows machine, and apart from that, I'm unsure what other information to provide. Below is the contents of the api.php and below that, those of the controller to which the form contents are processed (or not as is the case now!), the Vue method used when the form is submitted, and my JWT.php contents:

Route::apiResource('/question','QuestionController');
Route::apiResource('/category','CategoryController');
Route::apiResource('/question/{question}/reply','ReplyController');
Route::post('/like/{reply}','LikeController@likeIt');
Route::delete('/like/{reply}','LikeController@unLikeIt');

Route::group([

  'middleware' => 'api',
  'prefix' => 'auth'

], function ($router) {

  Route::post('login', 'AuthController@login');
  Route::post('logout', 'AuthController@logout');
  Route::post('signup', 'AuthController@signup');
  Route::post('refresh', 'AuthController@refresh');
  Route::post('me', 'AuthController@me');
  Route::post('payload', 'AuthController@payload');

QuestionController.php

namespace App\Http\Controllers;

use App\Models\Question;
use Illuminate\Http\Request;
use Symfony\Component\HttpFoundation\Response;
use App\Http\Resources\QuestionResource;
use App\Http\Requests\QuestionRequest;

class QuestionController extends Controller
{
  public function __construct()
  {
    $this->middleware('JWT', ['except' => ['index','show']]);
    //No one can create a question without having a token
  }

  public function store(Request $request)
  {
    $request['slug'] = str_slug($request->title);
    auth()->user()->question()->create($request->all());
    return response('Created', Response::HTTP_CREATED); 
}

Create.vue

:
methods: {
  create(){
     axios.post('/api/question',this.form)
     .then(res => console.log(res.data))
     .catch(error => this.errors = error.response.data.error)
  }...

My JWT.php contents are:

namespace App\Http\Middleware;

use Closure;
use JWTAuth;


class JWT
{
    public function handle($request, Closure $next)
    {
      JWTAuth::parseToken()->authenticate();
      //JWTAuth::toUser(JWTAuth::getToken());
      return $next($request);
    }
}

What else/where else do I look for the mistake I've made?

Thanks,

Tom

Upvotes: 0

Views: 4028

Answers (1)

TomBaine
TomBaine

Reputation: 773

The problem has been that I've been setting up the Authorization header in my app.js file as

const JWTtoken = `Bearer ${localStorage.getItem('token')}`;
window.axios.defaults.headers.common['Authorization'] = JWTtoken;

but 'Bearer' was/is being stripped from the header that is sent. So, I altered the method through which the form's contents were being sent to the server so that the Authorization header is added at that point:

        create(){
            const JWTtoken = `Bearer ${localStorage.getItem('token')}`;
            window.axios.defaults.headers.common['Authorization'] = JWTtoken;
            axios.post('/api/question',this.form)
                .then(res => console.log(res.data))
                .catch(error => this.errors = error.response.data.error)
        }

and everything now works.

Only three days spent on this problem!

Upvotes: 1

Related Questions