我有一条路线,我在那里使用auth中间件并且效果很好。
Route::group(['prefix' => 'v1','middleware' => ['auth:api']], function()
{
Route::resource('user', 'v1\MyController');
});
问题是我也希望这条路由也可以被非认证用户访问。有了上述内容,我收到401 Unauthorized错误,我无法为未经身份验证的用户返回任何内容。那么我如何验证这条路线(以便传递用户数据),同时即使用户未经过身份验证也允许路由继续进行?
(我尝试在路由器页面上进行有条件的Auth检查,但似乎用户已通过身份验证,因此它始终保持错误。)
编辑:我还应该注意,我使用的是带有密码授权和API的API路由。访问令牌。
答案 0 :(得分:3)
我遇到了同样的情况。
由于auth中间件仅检查经过身份验证的用户,因此我们可以为未经身份验证的用户使用客户端凭据。
客户端凭据在Laravel \ Passport \ Http \ Middleware \ CheckClientCredentails中有一个独立的中间件。
我创建了一个自定义中间件,将两个中间件组合在一起,允许其中一个通过。
这是我的自定义中间件
namespace Laravel\Passport\Http\Middleware;
use Closure;
use League\OAuth2\Server\ResourceServer;
use Illuminate\Auth\AuthenticationException;
use League\OAuth2\Server\Exception\OAuthServerException;
use Symfony\Bridge\PsrHttpMessage\Factory\DiactorosFactory;
class CheckClientCredentials
{
/**
* The Resource Server instance.
*
* @var ResourceServer
*/
private $server;
/**
* Create a new middleware instance.
*
* @param ResourceServer $server
* @return void
*/
public function __construct(ResourceServer $server)
{
$this->server = $server;
}
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @return mixed
*
* @throws \Illuminate\Auth\AuthenticationException
*/
public function handle($request, Closure $next, ...$scopes)
{
$psr = (new DiactorosFactory)->createRequest($request);
try{
$psr = $this->server->validateAuthenticatedRequest($psr);
} catch (OAuthServerException $e) {
throw new AuthenticationException;
}
foreach ($scopes as $scope) {
if (!in_array($scope,$psr->getAttribute('oauth_scopes'))) {
throw new AuthenticationException;
}
}
return $next($request);
}
}
Kernal.php
protected $routeMiddleware = [
'auth' => \Illuminate\Auth\Middleware\Authenticate::class,
'auth.api' => \App\Http\Middleware\APIAuthenticate::class,
....
路由\ api.php
Route::group([
'namespace' => 'API',
'middleware' => 'auth.api:api',
], function(){
....
答案 1 :(得分:2)
从当前路由组(应用auth中间件)中删除此路由。
然后
public function __construct()
{
if (array_key_exists('HTTP_AUTHORIZATION', $_SERVER)) {
$this->middleware('auth:api');
}
}
然后
if (Auth::check()) {
// Auth users
} else{
//Guest users
}
答案 2 :(得分:1)
请不要在auth中间件中为访客用户和经过身份验证的用户提供这些网址。因为auth中间件仅允许经过身份验证的用户。
要检查经过身份验证和未经身份验证的用户,您可以在视图中使用以下代码
@if (Auth::guest())
//For guest users
@else
//for authenticated users
@endif
已编辑:在控制器中使用
if (Auth::check()) {
// Auth users
} else{
//Guest users
}
答案 3 :(得分:1)
您可以使用此示例:
@if(Auth::user())
echo "authincatesd user";
@else
echo "unauthorised";
@endif
答案 4 :(得分:1)
从未经身份验证(未分配auth:api中间件)路由的处理程序方法中,尝试:
Auth::guard("api")->user();
如果已填充,则您不受保护的路由可以将访问视为已认证。如果不是,则表示该用户是随机访问该路线的用户,可以这样对待。
答案 5 :(得分:0)
@Yves 的回答几乎是正确的。但是一个小小的改变,
我们需要检查key值是否不为空,而不是array_key_exists。因为它总是有那个键但是空值。所以,而不是像这样的控制器构造检查授权标头。
if ($_SERVER['HTTP_AUTHORIZATION']) {
$this->middleware('auth:sanctum');
}
然后您可以像这样检查经过身份验证的用户:
if (auth()->check()) {
// User is logged in and you can access using
// auth()->user()
} else {
// Unauthenticated
}
答案 6 :(得分:0)
供圣所使用:
if (Auth::guard('sanctum')->check()) {
// user is logged in
/** @var User $user */ $user = Auth::guard('sanctum')->user();
} else {
// user is not logged in (no auth or invalid token)
}