当前位置: 首页 > 知识库问答 >
问题:

拉威尔护照镜

南宫兴德
2023-03-14

我对拉威尔望远镜的部分有点困惑。

我有一个用户模型和表。

如何为用户分配用户、客户和/或管理员的角色。

我有一个带有vue和laravel api后端的水疗中心。我用https://laravel.com/docs/5.3/passport#consuming-使用javascript创建api

    Passport::tokensCan([
        'user' => 'User',
        'customer' => 'Customer',
        'admin' => 'Admin',
    ]);

我如何分配哪个用户模型具有哪些作用域?

还是范围与角色不同?

您将如何实现这一点?

提前谢谢!

共有3个答案

公孙国兴
2023-03-14

我知道这有点晚了,但是如果您在SPA中使用Web中间件中的CreateFreshApiToken消耗后端API,那么您可以简单地将'admin'中间件添加到您的应用程序中:

PHP artisan make:中间件管理员

然后在\App\Http\Middleware\Admin执行以下操作:

public function handle($request, Closure $next)
{
    if (Auth::user()->role() !== 'admin') {
        return response(json_encode(['error' => 'Unauthorised']), 401)
            ->header('Content-Type', 'text/json');
    }

    return $next($request);
}

请确保已将角色方法添加到\App\User以检索用户角色。

现在,您只需在app\Http\Kernel中注册中间件。php$routeMiddleware,类似于:

protected $routeMiddleware = [
    // Other Middleware
    'admin' => \App\Http\Middleware\Admin::class,
];

并将其添加到routes/api中的路由中。php

Route::middleware(['auth:api','admin'])->get('/customers','Api\CustomersController@index');

现在,如果您试图未经许可访问api,您将收到“401 Unauthorized”错误,您可以在应用程序中检查并处理该错误。

解沈义
2023-03-14

实现Raymond-Lagonda响应,它工作得非常好,只是要注意以下几点。您需要覆盖ApiLoginController中AuthenticateUsers特性中的某些方法:

    /**
     * Send the response after the user was authenticated.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\Response
     */
    protected function sendLoginResponse(Request $request)
    {
        // $request->session()->regenerate(); // coment this becose api routes with passport failed here.

        $this->clearLoginAttempts($request);

        return $this->authenticated($request, $this->guard()->user())
                ?: response()->json(["status"=>"error", "message"=>"Some error for failes authenticated method"]);

    }

    /**
     * Get the failed login response instance.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\RedirectResponse
     */
    protected function sendFailedLoginResponse(Request $request)
    {
        return response()->json([
                                "status"=>"error", 
                                "message"=>"Autentication Error", 
                                "data"=>[
                                    "errors"=>[
                                        $this->username() => Lang::get('auth.failed'),
                                    ]
                                ]
                            ]);
    }

如果您将登录:用户名字段更改为自定义用户名字段,例如:电子邮件。您必须像在LoginController中一样优化用户名方法。您还必须重新定义和编辑方法:validateLogin、attemptLogin、credentials,因为一旦登录被验证,请求将转发到passport,并且必须称为username。

柯宜年
2023-03-14

还是范围与角色不同?

两者最大的区别是它们适用的上下文。基于角色的访问控制(RBAC)控制用户直接使用Web应用程序时的权限改造,而Oauth-2范围代表用户控制外部客户端对API资源的访问。

我如何分配哪个用户模型具有哪些作用域?

在一般的Oauth流中,请求用户(作为资源所有者)授权客户机处理它可以和不能代表他/她做的事情,这些就是所谓的范围。成功授权后,客户端请求的范围将分配给生成的令牌,而不是用户本身。

根据您选择的Oauth授权流,客户机应该在其请求中包含作用域。在授权代码授予流中,将用户重定向到授权页面时,范围应包含在HTTP GET查询参数中,而在密码授予流中,范围必须包含在HTTP POST body参数中,才能请求令牌。

您将如何实现这一点?

这是一个密码授予流的示例,假设您事先完成了laravel/passport设置

定义管理员和用户角色的作用域。尽可能具体,例如:管理员可以管理订单,用户只能阅读。

// in AuthServiceProvider boot
Passport::tokensCan([
    'manage-order' => 'Manage order scope'
    'read-only-order' => 'Read only order scope'
]);

准备REST控制器

// in controller
namespace App\Http\Controllers;

class OrderController extends Controller
{   
    public function index(Request $request)
    {
        // allow listing all order only for token with manage order scope
    }

    public function store(Request $request)
    {
        // allow storing a newly created order in storage for token with manage order scope
    }

    public function show($id)
    {
        // allow displaying the order for token with both manage and read only scope
    }
}

使用api防护和范围分配路线

// in api.php
Route::get('/api/orders', 'OrderController@index')
    ->middleware(['auth:api', 'scopes:manage-order']);
Route::post('/api/orders', 'OrderController@store')
    ->middleware(['auth:api', 'scopes:manage-order']);
Route::get('/api/orders/{id}', 'OrderController@show')
    ->middleware(['auth:api', 'scopes:manage-order, read-only-order']);

当发出令牌时,首先检查用户角色并基于该角色授予作用域。为了实现这一点,我们需要一个额外的控制器,它使用AuthenticatesUsers特性来提供登录endpoint。

namespace App\Http\Controllers\Auth;

use App\Http\Controllers\Controller;
use Illuminate\Foundation\Auth\AuthenticatesUsers;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Route;

class ApiLoginController extends Controller
{
    use AuthenticatesUsers;

    protected function authenticated(Request $request, $user)
    {               
        // implement your user role retrieval logic, for example retrieve from `roles` database table
        $role = $user->checkRole();

        // grant scopes based on the role that we get previously
        if ($role == 'admin') {
            $request->request->add([
                'scope' => 'manage-order' // grant manage order scope for user with admin role
            ]);
        } else {
            $request->request->add([
                'scope' => 'read-only-order' // read-only order scope for other user role
            ]);
        }

        // forward the request to the oauth token request endpoint
        $tokenRequest = Request::create(
            '/oauth/token',
            'post'
        );
        return Route::dispatch($tokenRequest);
    }
}

为api登录endpoint添加路由

//in api.php
Route::group('namespace' => 'Auth', function () {
    Route::post('login', 'ApiLoginController@login');
});

不要执行POST-to/oauth/token路由,而是发布到我们之前提供的api登录endpoint

// from client application
$http = new GuzzleHttp\Client;

$response = $http->post('http://your-app.com/api/login', [
    'form_params' => [
        'grant_type' => 'password',
        'client_id' => 'client-id',
        'client_secret' => 'client-secret',
        'username' => 'user@email.com',
        'password' => 'my-password',
    ],
]);

return json_decode((string) $response->getBody(), true);

成功授权后,将为客户端应用程序发出一个基于我们之前定义的作用域的访问\u令牌和刷新\u令牌。将其保留在某个地方,并在向API发出请求时将令牌包含到HTTP头中。

// from client application
$response = $client->request('GET', '/api/my/index', [
    'headers' => [
        'Accept' => 'application/json',
        'Authorization' => 'Bearer '.$accessToken,
    ],
]);

API现在应该返回了

{"error":"unauthenticated"}

每当使用具有under权限的令牌访问受限endpoint时。

 类似资料:
  • 我目前正在研究构建SaaS构建管理工具。我想知道的是,如果我使用laravel passport作为api令牌,我如何为用户分配角色,例如: SuperAdmin:可以创建项目|可以创建新用户并为用户分配角色。 管理员:可以查看项目。 因为我希望能够根据用户权限隐藏前端上的元素。 例如,如果我使用传统的laravel应用程序,我可以使用委托和刀片指令@role('admin')来显示基于用户权限类

  • 我有点困惑于认识到和包之间的差异。它们实际上通过令牌服务于相同的API身份验证目的吗?只要Laravel Pasport是在5.3中引入的,在最新版本中是否应该使用Pasport而不是包?

  • 是否还要向findForPassport添加或传递1个变量? 在默认的laravel passport登录中,我只能传递2个变量(用户名、密码),但我想再传递1个变量,并在findForPassport中检查该用户是否属于其他表。

  • 突然,当尝试通过护照创建JWT时,我开始在生产中遇到此错误,运行在Ubuntu / apache2上。据我所知,服务器上没有任何更改,没有安装,没有部署,它只是停止工作。 PHP 7.3 OpenSSL 1.0.1f Laravel 5.8 我还注意到这个错误的另一个版本。没有什么变化,所以我不知道为什么会出现这种错误。 注意这一点:

  • 我对Laravel截断的数据有一个小问题。我将传递给我的后端值,该值可以是表中定义的“百分比”或“金额”,但在表中也可以为null,但每次尝试将其设置为null时,都会出现如下错误: {"discount_currency":["您输入的值无效。"]} 或者当我从处理请求中删除enum时,它会说 所以我传递数据抛出API从我的Vue,这个婴儿车的请求看起来像: 所以如果我删除...我有第二个错误。

  • 我正在构建一个Laravel web应用程序,其中我需要一个动态图像库,我构建了一个后端管理面板,可以在其中添加图像,我成功地将图像添加并保存到数据库中,但我无法编辑或删除它们。 错误是: UrlGenerationException中的ErrorException。php第17行:缺少[Route:galleries.update][URI:backend/galleries/{gallery}