1

Hi i'm created a web service with Slim from a course of lynda "Building APIs in PHP Using the Slim Micro Framework" but when i want login, this error Occurs

Notice: Undefined offset: 0 in C:\wamp64\www\lynda2\src\Chatter\Middleware\Authentication.php on line 12

Authentication





    namespace Chatter\Middleware;

    use Chatter\Models\User;

    class Authentication
    {
        public function __invoke($request, $response, $next)
        {
            $auth = $request->getHeader('Authorization');
            $_apikey = $auth[0];
            $apikey = substr($_apikey, strpos($_apikey, ' ') + 1);

            $user = new User();
            if (!$user->authenticate($apikey)) {
                $response->withStatus(401);

                return $response;
            }

            $response = $next($request, $response);

            return $response;
        }
    }
    
    
User.php


<pre><code>


namespace Chatter\Models;

class User extends \Illuminate\Database\Eloquent\Model
{
    public function authenticate($apikey)
    {
        $user = User::where('apikey', '=', $apikey)->take(1)->get();
        $this->details = $user[0];

        return ($user[0]->exists) ? true : false;
    }
}

</code></pre>

index.php

<pre><code>

require 'vendor/autoload.php';
include 'bootstrap.php';

use Chatter\Models\Message;
use Chatter\Middleware\Logging as ChatterLogging;
use Chatter\Middleware\Authentication as ChatterAuth;

$app = new \Slim\App();
$app->add(new ChatterAuth());
$app->add(new ChatterLogging());

$app->get('/messages', function ($request, $response, $args) {
    $_message = new Message();

    $messages = $_message->all();

    $payload = [];
    foreach($messages as $_msg) {
        $payload[$_msg->id] = ['body' => $_msg->body, 'user_id' => $_msg->user_id, 'created_at' => $_msg->created_at];
    }

    return $response->withStatus(200)->withJson($payload);
});


$app->get('/', function ($request, $response, $args) {
    return "This is a catch all route for the root that doesn't do anything useful.";
});

// Run app
$app->run();



</code></pre>
EhSAn
  • 111
  • 3
  • 12

2 Answers2

2

The error is stating that when you "login" there is no Authorization header present.

$request->getHeader('Authorization') returns an empty array, so when you attempting to access the first element of the array, you get your error:

$_apikey = $auth[0]; // Will trigger error, since there are no elements in the array

Thus to aviod this error, get $apikey like this:

public function __invoke($request, $response, $next)
{
    $auth = $request->getHeader('Authorization');
    $_apikey = array_shift($auth);
    if ($_apikey) {
        $apikey = substr($_apikey, strpos($_apikey, ' ') + 1);
        $user = new User();
        if (!$user->authenticate($apikey)) {
            return $response->withStatus(401);
        } else {
            return $next($request, $response);
        }
    } else {
        // Authorization header is missing, therefore unauthorized access
        return $response->withStatus(401);
    }
}
Georgy Ivanov
  • 1,573
  • 1
  • 17
  • 24
geggleto
  • 2,605
  • 1
  • 15
  • 18
0

This is an older thread, but in case anyone else is following this tutorial ... the code the OP posted was supposed to do exactly what it does - to fail if there is no authorization header present. Looks like the OP missed one step: adding the bearer token to the request. In Postman, go to Authorization > Type > Bearer Token and paste a valid token in the input field. I believe that it was clearly stated in the tutorial. Afterward, everything works as expected.

  • 1
    I am pretty sure that this is basically a good contribution. But could you rephrase it to be more obviously an answer? Ideally according to [answer]. And you might find taking the [tour] useful. – Yunnosch Jun 10 '21 at 11:34