Lumen HTTP Basic Authentication without using a database

I am creating a RESTful API using Lumen and would like to add basic HTTP authentication for security.

In the routes.php file routes.php it sets the auth.basic value for each route:

 $app->get('profile', ['middleware' => 'auth.basic', function() { // logic here }]); 

Now, when I go to http://example-api.local/profile , now I request basic HTTP authentication, which is good. But when I try to log in, I get this error message: Fatal error: Class '\App\User' not found in C:\..\vendor\illuminate\auth\EloquentUserProvider.php on line 126

I do not want user checks to be performed in the database, since I will only have one account code, so most likely it will just get the username and password for the variable and check it from there.

Btw, I refer to this laracast tutorial . Although this is a training application for Laravel, I implement it in the Lumen application.

+6
source share
3 answers

I answer my question because I managed to get it to work, but I still would like to know more about other opinions regarding my decision and the correct way to create it.

I was able to work on this by creating my own middleware that does this:

 <?php namespace App\Http\Middleware; use Closure; class HttpBasicAuth { /** * Handle an incoming request. * * @param \Illuminate\Http\Request $request * @param \Closure $next * @return mixed */ public function handle($request, Closure $next) { $envs = [ 'staging', 'production' ]; if(in_array(app()->environment(), $envs)) { if($request->getUser() != env('API_USERNAME') || $request->getPassword() != env('API_PASSWORD')) { $headers = array('WWW-Authenticate' => 'Basic'); return response('Unauthorized', 401, $headers); } } return $next($request); } } 

If you look at the code, it is quite simple and works well. Although I am wondering if there is a β€œLaravel” way to do this, since the above code is simple PHP code that does basic HTTP authentication.

If you notice, the username and password verification is hardcoded in the .env file, since I do not see the need to access the database for verification.

+11
source

Check your bootstrap/app.php . Make sure you register your auth.basic , something like this:

 $app->routeMiddleware([ 'auth.basic' => Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class, ]); 

After that, change your routes:

 $app->get('/profile', ['middleware' => 'auth.basic', function() { // Logic }]); 

EDIT

If you want to use database instead of eloquent authentication, you can call:

 Auth::setDefaultDriver('database'); 

Before attempting authentication:

 Auth::attempt([ 'email' => ' info@foo.bar ', 'password' => 'secret', ]); 

Edit No. 2

If you want AuthManager , you can define your own driver for the AuthManager class:

 Auth::setDefaultDriver('basic'); Auth::extend('basic', function () { return new App\Auth\Basic(); }); 

And below is the App\Auth\Basic class of the App\Auth\Basic class:

 <?php namespace App\Auth; use Illuminate\Contracts\Auth\UserProvider; use Illuminate\Contracts\Auth\Authenticatable; class Basic implements UserProvider { /** * Retrieve a user by their unique identifier. * * @param mixed $identifier * @return \Illuminate\Contracts\Auth\Authenticatable|null */ public function retrieveById($identifier) { } /** * Retrieve a user by their unique identifier and "remember me" token. * * @param mixed $identifier * @param string $token * @return \Illuminate\Contracts\Auth\Authenticatable|null */ public function retrieveByToken($identifier, $token) { } /** * Update the "remember me" token for the given user in storage. * * @param \Illuminate\Contracts\Auth\Authenticatable $user * @param string $token * @return void */ public function updateRememberToken(Authenticatable $user, $token) { } /** * Retrieve a user by the given credentials. * * @param array $credentials * @return \Illuminate\Contracts\Auth\Authenticatable|null */ public function retrieveByCredentials(array $credentials) { return new User($credentials); } /** * Validate a user against the given credentials. * * @param \Illuminate\Contracts\Auth\Authenticatable $user * @param array $credentials * @return bool */ public function validateCredentials(Authenticatable $user, array $credentials) { $identifier = $user->getAuthIdentifier(); $password = $user->getAuthPassword(); return ($identifier === ' info@foobarinc.com ' && $password === 'password'); } } 

Please note that the validateCredentials method of the first argument requires the implementation of the Illuminate\Contracts\Auth\Authenticatable interface, so you need to create your own User class:

 <?php namespace App\Auth; use Illuminate\Support\Fluent; use Illuminate\Contracts\Auth\Authenticatable; class User extends Fluent implements Authenticatable { /** * Get the unique identifier for the user. * * @return mixed */ public function getAuthIdentifier() { return $this->email; } /** * Get the password for the user. * * @return string */ public function getAuthPassword() { return $this->password; } /** * Get the token value for the "remember me" session. * * @return string */ public function getRememberToken() { } /** * Set the token value for the "remember me" session. * * @param string $value * @return void */ public function setRememberToken($value) { } /** * Get the column name for the "remember me" token. * * @return string */ public function getRememberTokenName() { } } 

And you can check your own driver using the Auth::attempt method:

 Auth::setDefaultDriver('basic'); Auth::extend('basic', function () { return new App\Auth\Basic(); }); dd(Auth::attempt([ 'email' => ' info@foobarinc.com ', 'password' => 'password', ])); // return true 
+2
source

First, we will extend AuthenticateWithBasicAuth in our middleware.

 <?php namespace App\Http\Middleware; use \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth; class HttpBasicAuth extends AuthenticateWithBasicAuth { } 

In config / auth.php create a custom defender and we will use custom_http_guard with HttpBasicAuth.

 'guards' => [ 'web' => [ 'driver' => 'session', 'provider' => 'users', ], 'api' => [ 'driver' => 'token', 'provider' => 'users', ], 'custom_http_guard' => [ 'driver' => 'token', 'provider' => 'custom_http_provider', ], ], 

We will use the default Larvel driver token.

 'providers' => [ 'users' => [ 'driver' => 'eloquent', 'model' => App\User::class, ], 'custom_http_provider' => [ 'data' => [ 'email' => ' info@foo.bar ', 'password' => 'secret', ] ], ], 

If you can find a way to return the data as above. Then you download and get code that complies with laravel standards.

Hope you have an idea! Looking for the final solution. If someone can complete :)

Waibhav Arora

0
source

Source: https://habr.com/ru/post/1239122/


All Articles