laravel 不使用数据库的 Lumen HTTP 基本身份验证
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/34451337/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Lumen HTTP Basic Authentication without use of database
提问by basagabi
I'm creating a RESTful API using Lumen and would like to add HTTP basic Authentication for security.
我正在使用 Lumen 创建一个 RESTful API,并希望添加 HTTP 基本身份验证以确保安全。
On the routes.php
file, it set the auth.basic
middle for every routes:
在routes.php
文件中,它auth.basic
为每条路由设置了中间值:
$app->get('profile', ['middleware' => 'auth.basic', function() {
// logic here
}]);
Now when I access http://example-api.local/profile
I am now prompted with the HTTP basic authentication, which is good. But when I try to login, I get this error message: Fatal error: Class '\App\User' not found in C:\..\vendor\illuminate\auth\EloquentUserProvider.php on line 126
现在,当我访问http://example-api.local/profile
时,系统会提示我进行 HTTP 基本身份验证,这很好。但是当我尝试登录时,我收到此错误消息:Fatal error: Class '\App\User' not found in C:\..\vendor\illuminate\auth\EloquentUserProvider.php on line 126
I do not want the validation of users to be done on a database since I will just have one credential so most likely it will just get the username and password on a variable and validate it from there.
我不希望在数据库上完成用户验证,因为我只有一个凭据,因此很可能它只会获取变量上的用户名和密码并从那里验证它。
Btw, I reference it thru this laracast tutorial. Though it is a Laravel app tutorial, I am implementing it on Lumen app.
顺便说一句,我通过这个laracast 教程引用了它。虽然它是一个 Laravel 应用程序教程,但我正在 Lumen 应用程序上实现它。
回答by basagabi
I am answering my own question as I was able to make it work but would still like to know more insights from others regarding my solution and the proper laravel way of doing it.
我正在回答我自己的问题,因为我能够使它工作,但仍然想从其他人那里了解更多关于我的解决方案和正确的 Laravel 方法的见解。
I was able to work on this by creating a custom 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'll look into the code, it is pretty basic and works well. Though I am wondering if there is a "Laravel" way of doing this as the code above is a plain PHP code that does HTTP basic authentication.
如果您查看代码,它是非常基本的并且运行良好。尽管我想知道是否有一种“Laravel”方式可以做到这一点,因为上面的代码是一个执行 HTTP 基本身份验证的普通 PHP 代码。
If you'll notice, validation of username and password is hard coded on the .env
file as I do not see the need for database access for validation.
如果您会注意到,用户名和密码的验证是硬编码在.env
文件上的,因为我认为不需要访问数据库进行验证。
回答by krisanalfa
Check your bootstrap/app.php
. Make sure you have registered your auth.basic
middleware, something like this:
检查您的bootstrap/app.php
. 确保您已注册您的auth.basic
中间件,如下所示:
$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 may call:
如果您想使用database
而不是eloquent
身份验证,您可以调用:
Auth::setDefaultDriver('database');
Before you attempt to authenticate:
在您尝试进行身份验证之前:
Auth::attempt([
'email' => '[email protected]',
'password' => 'secret',
]);
Edit #2
编辑 #2
If you wish to authenticate in hardcode ways, you may define your own driver for AuthManager
class:
如果您希望以硬编码方式进行身份验证,您可以为AuthManager
类定义自己的驱动程序:
Auth::setDefaultDriver('basic');
Auth::extend('basic', function () {
return new App\Auth\Basic();
});
And then below is the basic of App\Auth\Basic
class:
然后下面是App\Auth\Basic
类的基础:
<?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 === '[email protected]' && $password === 'password');
}
}
Note that validateCredentials
method needs first argument is an implementation of Illuminate\Contracts\Auth\Authenticatable
interface, so you need to create you own User
class:
请注意,validateCredentials
方法需要的第一个参数是Illuminate\Contracts\Auth\Authenticatable
接口的实现,因此您需要创建自己的User
类:
<?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 may test your own driver via Auth::attempt
method:
您可以通过以下Auth::attempt
方法测试您自己的驱动程序:
Auth::setDefaultDriver('basic');
Auth::extend('basic', function () {
return new App\Auth\Basic();
});
dd(Auth::attempt([
'email' => '[email protected]',
'password' => 'password',
])); // return true
回答by Vaibhav
First we will extend AuthenticateWithBasicAuth in our middleware.
首先,我们将在我们的中间件中扩展 AuthenticateWithBasicAuth。
<?php
namespace App\Http\Middleware;
use \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth;
class HttpBasicAuth extends AuthenticateWithBasicAuth
{
}
In config/auth.php create custom guard and we will use custom_http_guard with HttpBasicAuth.
在 config/auth.php 创建自定义守卫,我们将使用 custom_http_guard 和 HttpBasicAuth。
'guards' => [
'web' => [
'driver' => 'session',
'provider' => 'users',
],
'api' => [
'driver' => 'token',
'provider' => 'users',
],
'custom_http_guard' => [
'driver' => 'token',
'provider' => 'custom_http_provider',
],
],
We will use Laravel's default 'token' driver.
我们将使用 Laravel 的默认“令牌”驱动程序。
'providers' => [
'users' => [
'driver' => 'eloquent',
'model' => App\User::class,
],
'custom_http_provider' => [
'data' => [
'email' => '[email protected]',
'password' => 'secret',
]
],
],
If you can find the way to return data like above.Then you rock and get code following laravel standards.
如果你能找到像上面那样返回数据的方法,那么你就会摇滚并获得遵循 Laravel 标准的代码。
Hope you got the idea! Looking for final solution. If someone can complete :)
希望你有这个想法!寻找最终解决方案。如果有人可以完成:)
Vaibhav Arora
瓦巴夫·阿罗拉