Hi. 401 Unauthorized error means you are not authenticated, you need to send your api token with every requests. Take a look at this: https://stackoverflow.com/questions/43281009/laravel-5-4-api-route-401
401 Unauthenticated Error [HELP]
Hi all,
Having a totally brain freeze here...I'm trying to post to the MessageBird API to send an SMS using Ajax.
$("#mob").on('focusout', function(e){
e.preventDefault();
$.ajax({
type: 'POST',
url: '/api/mobile/messagebird',
data: {'number': mob },
dataType: 'json',
success: function (data) {
console.log('Success');
},
error: function (data) {
console.log('An error occurred.');
console.log(data);
},
});
});
And my controller looks like:
public function sendSMS(Request $request)
{
try {
$client = new \MessageBird\Client('key from env');
$message = new \MessageBird\Objects\Message();
$message->originator = 'MessageBird';
$message->recipients = '44750000000';
$message->body = 'This is a test message.';
$MessageResult = $client->messages->create(json_encode($Message));
/// var_dump($MessageResult);
return response()->json([
'success' => true,
'response' => json_encode($MessageResult)
]);
} catch (\MessageBird\Exceptions\AuthenticateException $e) {
// That means that your accessKey is unknown
echo 'wrong login';
} catch (\MessageBird\Exceptions\BalanceException $e) {
// That means that you are out of credits, so do something about it.
echo 'no balance';
} catch (\Exception $e) {
echo $e->getMessage();
}
}
But I keep seeing "Unauthenticated." and I'm not sure why. Can someone kindly help me out please.
By the way I have the CSRF except set also so this shouldn't interfere.
Try to hardcode your api key into the client constructor. This will determine if the problem is with your code or with your account.
EDIT: I assumed the error was happening on the call to the service as opposed to the call to your app.
I’m not using the Api routes either this is just within the web routes with no middleware
Did you prevent the middleware from being applied in your RouteServiceProvider::mapApiRoutes()?
Can you try changing the route to not start with api/ and see if it changes anything?
I removed the api part and now get
message: "", exception: "Symfony\Component\HttpKernel\Exception\HttpException",…}
exception
:
"Symfony\Component\HttpKernel\Exception\HttpException"
file
:
"/Users/lee/code/cr/vendor/laravel/framework/src/Illuminate/Foundation/Exceptions/Handler.php"
The full stack trace would be helpful. Can't really tell what the problem is from that excerpt.
Sorry my bad, I thought i Had
message: "", exception: "Symfony\Component\HttpKernel\Exception\HttpException",…}
exception
:
"Symfony\Component\HttpKernel\Exception\HttpException"
file
:
"/Users/lee/code/cr/vendor/laravel/framework/src/Illuminate/Foundation/Exceptions/Handler.php"
line
:
203
message
:
""
trace
:
[{,…}, {file: "/Users/lee/code/cr/app/Exceptions/Handler.php", line: 85, function: "render",…},…]
0
:
{,…}
1
:
{file: "/Users/lee/code/cr/app/Exceptions/Handler.php", line: 85, function: "render",…}
2
:
{file: "/Users/lee/code/cr/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php", line: 83,…}
3
:
{file: "/Users/lee/code/cr/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php", line: 55,…}
4
:
{,…}
5
:
{file: "/Users/lee/code/cr/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", line: 151,…}
6
:
{file: "/Users/lee/code/cr/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php", line: 53,…}
7
:
{,…}
8
:
{file: "/Users/lee/code/cr/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", line: 151,…}
9
:
{file: "/Users/lee/code/cr/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php", line: 53,…}
10
:
{,…}
11
:
{file: "/Users/lee/code/cr/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", line: 151,…}
12
:
{file: "/Users/lee/code/cr/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php", line: 53,…}
13
:
{,…}
14
:
{file: "/Users/lee/code/cr/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", line: 151,…}
15
:
{file: "/Users/lee/code/cr/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php", line: 53,…}
16
:
{file: "/Users/lee/code/cr/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", line: 104,…}
17
:
{file: "/Users/lee/code/cr/vendor/laravel/framework/src/Illuminate/Routing/Router.php", line: 667,…}
18
:
{file: "/Users/lee/code/cr/vendor/laravel/framework/src/Illuminate/Routing/Router.php", line: 642,…}
19
:
{file: "/Users/lee/code/cr/vendor/laravel/framework/src/Illuminate/Routing/Router.php", line: 608,…}
20
:
{file: "/Users/lee/code/cr/vendor/laravel/framework/src/Illuminate/Routing/Router.php", line: 597,…}
21
:
{file: "/Users/lee/code/cr/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php",…}
22
:
{file: "/Users/lee/code/cr/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php", line: 30,…}
23
:
{file: "/Users/lee/code/cr/vendor/barryvdh/laravel-debugbar/src/Middleware/InjectDebugbar.php",…}
24
:
{file: "/Users/lee/code/cr/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", line: 151,…}
25
:
{file: "/Users/lee/code/cr/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php", line: 53,…}
26
:
{file: "/Users/lee/code/cr/vendor/fideloper/proxy/src/TrustProxies.php", line: 57,…}
27
:
{file: "/Users/lee/code/cr/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", line: 151,…}
28
:
{file: "/Users/lee/code/cr/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php", line: 53,…}
29
:
{,…}
30
:
{file: "/Users/lee/code/cr/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", line: 151,…}
31
:
{file: "/Users/lee/code/cr/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php", line: 53,…}
32
:
{,…}
33
:
{file: "/Users/lee/code/cr/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", line: 151,…}
34
:
{file: "/Users/lee/code/cr/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php", line: 53,…}
35
:
{,…}
36
:
{file: "/Users/lee/code/cr/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", line: 151,…}
I was wrong, that wasn't very useful at all. Your log file might have a more readable stack trace, but regardless, can you verify if your controller method is being hit at all by adding a dd() to the top of it or logging something to a file, or just immediately returning some dummy data?
Even adding a dd() and removing all the MessageBird code along with adding
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
},
To the ajax this still shows as unauthenticated
So it went back to unauthenticated after progressing to that other error?
That is odd indeed, especially if you're on a route that isn't using the auth or api middelwares. I'm stumped.
@36864 yeah, me too!
As a sanity check, can you try doing the same request through a regular form instead of through ajax?
Yes I was going to do that, but then moved the route into my register route group and now I get a 302 response, but still doesn't show anything :(
I have no idea what your register route group does so I wouldn't know what effects that had. Presumably you have a middleware in place to prevent authenticated users to register again, so trying to access a route in the register group would redirect to the home page?
Yes that would explain the 302 code, so that's not right at all then. Guess I'll try in the conventional form way, rather than ajax, although it would need to be ajax.
Yes even with a conventional form it redirect to the login page, so the people who set this up before me did this, question is how do I get around this now?
I understand, but the first step here will be to actually manage to hit your controller code.
For now, just make the route something that is ungrouped, and not in the api prefix. Something like Route::post('sms', 'SmsController@sms')->name('sms') and call it through a <form method="POST" action="{{route('sms')}}>.
We'll work our way up from there.
EDIT: If you're being redirected to the login page, just login?
So I setup a basic form:
<form action="{{ route('sendsms') }}" method="post">
<div class="form-group">
<label for="tel" class="sr-only">Mobile Number</label>
<input id="mob" type="tel" class="form-control" name="mob" placeholder="Mobile Number" value="{{ old('tel', session()->get('company.basic.data.mob')) }}" >
<button class="btn btn-xs btn-primary" data-toggle="modal" data-target="#verifyModal">Verify</button>
</div>
<button type="submit">Send</button>
</form>
Pointing to a route a the top of the web routes files, so totally un-grouped.
Route::any('mobile/messagebird', 'ApiController@sendSMS')->name('sendsms');
But still redirects to /login
A route at the top of the web routes file is not ungrouped, it is in the webgroup, as defined in your RouteServiceProvider by default. Please check there and in your Http\Kernel.php for any middleware that's being applied to the webgroup.
I meant ungrouped as in not within any prefix or have any middleware attached to it.
Within Kernel it looks like:
'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,
],
Can you clear your caches, and then try again, and post the HTTP request to the server and the response you get please?
php artisan route:clear
php artisan view:clear
php artisan config:clear
php aritsan clear-compiled
composer dumpautoload
Still the same, redirect to login
At this point that just doesn't make any sense. I'm gonna ask you to post the following files in full. Obviously, mask any sensitive details or credentials, but please don't omit any code:
- RouteServiceProvider.php
- Http\Kernel.php
- ApiController.php
- web.php
RouteServiceProvider
<?php
namespace App\Providers;
use Illuminate\Support\Facades\Route;
use Illuminate\Foundation\Support\Providers\RouteServiceProvider as ServiceProvider;
class RouteServiceProvider extends ServiceProvider
{
/**
* This namespace is applied to your controller routes.
*
* In addition, it is set as the URL generator's root namespace.
*
* @var string
*/
protected $namespace = 'App\Http\Controllers';
/**
* Define your route model bindings, pattern filters, etc.
*
* @return void
*/
public function boot()
{
//
parent::boot();
}
/**
* Define the routes for the application.
*
* @return void
*/
public function map()
{
$this->mapApiRoutes();
$this->mapWebRoutes();
//
}
/**
* Define the "web" routes for the application.
*
* These routes all receive session state, CSRF protection, etc.
*
* @return void
*/
protected function mapWebRoutes()
{
Route::middleware('web')
->namespace($this->namespace)
->group(base_path('routes/web.php'));
}
/**
* Define the "api" routes for the application.
*
* These routes are typically stateless.
*
* @return void
*/
protected function mapApiRoutes()
{
Route::prefix('api')
->middleware('api')
->namespace($this->namespace)
->group(base_path('routes/api.php'));
}
}
Kernel:
<?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,
\App\Http\Middleware\TrustProxies::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',
],
];
/**
* 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,
'isVerified' => \App\Http\Middleware\IsVerified::class,
'isNotVerified' => \App\Http\Middleware\IsNotVerified::class,
'verifyRegisterType' => \App\Http\Middleware\VerifyRegisterType::class,
'verifyRegistrationStage' => \App\Http\Middleware\VerifyRegistrationStage::class,
'isPartOfAgency' => \App\Http\Middleware\IsPartOfAgency::class,
'isEmployed' => \App\Http\Middleware\IsEmployed::class,
'isAdmin' => \App\Http\Middleware\IsAdmin::class,
'vagrant' => \App\Http\Middleware\RedirectIfNotPartOfCompany::class,
'hasNotRequested' => \App\Http\Middleware\HasNotRequested::class,
'isTenant' => \App\Http\Middleware\IsTenant::class,
'hasAcceptedTos' => \App\Http\Middleware\HasAcceptedTos::class,
'isSubscribed' => \App\Http\Middleware\IsSubscribed::class,
'isBranchManager' => \App\Http\Middleware\IsBranchManager::class
];
}
API Controller as no middleware on it and has many methods but the one of interest is here:
class ApiController extends Controller
{
public function sendSMS(Request $request)
{
try {
$client = new \MessageBird\Client('XXXXXXXXX');
$message = new \MessageBird\Objects\Message();
$message->originator = 'MessageBird';
$message->recipients = '44750000000';
$message->body = 'This is a test message.';
$MessageResult = $client->messages->create($Message);
/// var_dump($MessageResult);
return response()->json([
'success' => true,
'response' => $MessageResult
]);
} catch (\MessageBird\Exceptions\AuthenticateException $e) {
// That means that your accessKey is unknown
echo 'wrong login';
} catch (\MessageBird\Exceptions\BalanceException $e) {
// That means that you are out of credits, so do something about it.
echo 'no balance';
} catch (\Exception $e) {
echo $e->getMessage();
}
}
}
The beginning of the routes file is as follows:
<?php
/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
|
| Here is where you can register web routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| contains the "web" middleware group. Now create something great!
|
*/
// Homepage route.
Route::get('/', function() {
return redirect('login');
});
/* MessageBird API */
Route::any('mobile/messagebird', 'ApiController@sendSMS')->name('sendsms');
// Auth routes.
Auth::routes();
Does the api controller use any traits? Is there any middleware in the base Controller that it extends? Also, what is its namespace?
No traits and it extends the base controller which does have:
public function __construct()
{
$this->middleware('auth');
}
Which if I comment that out it does work now.
And I have no idea why that is there within the base controller, this is a app I have recently undertaken
Please or to participate in this conversation.