sdwru/laravel-firebase-auth-plus

使用Google Firebase Auth保护您的Laravel API,并获取完整的Firebase Admin SDK

1.0 2020-06-02 21:37 UTC

This package is auto-updated.

Last update: 2024-09-22 23:34:46 UTC


README

使用Google Firebase Auth保护您的Laravel API

中间件添加到您的Laravel API中,可以确保只有使用由Google Firebase Auth签发的有效bearer token才能访问。

本包与我们所分叉的包的主要区别在于,我们使用laravel-firebase作为依赖项。使用laravel-firebase而不是firebase-tokens消除了对服务提供者的需求,因为它已经包含在laravel-firebase中。由于该包依赖于firebase-php,您还可以使用firebase-php提供的所有功能

角色中间件

本包包含可选的角色中间件以实现更细粒度的访问。

安装

composer require sdwru/laravel-firebase-auth-plus

laravel-firebase

如果尚未完成,请发布laravel-firebase ServiceProvider (Provider: Kreait\Laravel\Firebase\ServiceProvider)。

php artisan vendor:publish

根据他们的说明配置laravel-firebase,并在官方Firebase文档此链接中也有说明。

这些说明听起来比实际上要复杂。我们所需做的只是生成一个JSON文件,如下所示

  1. 在Firebase控制台中,打开设置 > 服务帐户。
  2. 点击生成新私钥,然后通过点击生成密钥来确认。
  3. 安全地存储生成的JSON文件,并在您的laravel .env文件中添加对该文件的引用。以下示例假设我们将其存储在laravel安装的根目录中。将其重命名为您想要的任何名称。
FIREBASE_CREDENTIALS=myproject-firebase-adminsdk.json

使用方法

有两种使用方法。

方法1. 无JWT令牌锁定所有访问

在您的app/Http/Kernel.php文件上添加中间件

\sdwru\LaravelFirebaseAuth\Middleware\JWTAuth::class,

请参阅Laravel中间件文档,了解在哪里将此放在您的Kernel.php文件中以及在路由中如何使用它。

方法2(推荐)使用认证保护者。

app/Providers/AuthServiceProvider.php中的boot方法中添加保护者。

public function boot()
{
   $this->registerPolicies();

   $this->app['auth']->viaRequest('firebase', function ($request) {
       return app(\sdwru\LaravelFirebaseAuth\Guard::class)->user($request);
   });
}

config/auth.php中设置您的api保护者驱动程序为firebase,并将模型设置为LaravelFirebaseAuth\User::class

    'guards' => [
        'web' => [
            'driver' => 'session',
            'provider' => 'users',
        ],

        'api' => [
            'driver' => 'firebase',
            'provider' => 'firebase',
        ],
    ],
    
    'providers' => [
        'users' => [
            'driver' => 'eloquent',
            'model' => App\User::class,
        ],

        'firebase' => [
            'driver' => 'firebase',
            'model' => \sdwru\LaravelFirebaseAuth\User::class,
        ],
],

routes/api.php中将认证添加到api路由。

Route::middleware('auth:api')->get('/user', function (Request $request) {
    return $request->user();
    //return true;
});

Route::middleware('auth:api')->apiResource('some_endpoint', 'API\SomeEndpointController');

示例:从API UserController获取uid(仅针对方法#2)

<?php
namespace App\Http\Controllers\API;

use Illuminate\Http\Request;
use Illuminate\Contracts\Auth\Guard;

class UserController extends Controller
{
    public function foo(Request $request, Guard $guard)
    {
        
        // Retrieve Firebase uid from id token via request
        $user = $request->user();
        $uid = $user->getAuthIdentifier();
        
        // Or, do the same thing using Laravel auth guard instead
        $user = $guard->user();
        $uid = $user->getAuthIdentifier();
        
        
        // Do something with the request for this user
    }
}

示例:检查是否已登录,并在Laravel的几乎任何地方检索firebase用户对象和uid(仅针对方法#2)

use Illuminate\Support\Facades\Auth;

class SomeClass
{
  public function bar()
  {
     //Check if logged in and retrieve user object and uid using Laravel Auth Facade
     $isLoggedIn = Auth::guard('api')->check();
     $userObject = Auth::guard('api')->user();
     $uid = Auth::guard('api')->id();
     
     //Alternatively, use Laravel auth() helper
     $isLoggedIn = auth('api')->check();
     $userObject = auth('api')->user();
     $uid = auth('api')->id();
     
  }
}

角色中间件

要使用此可选功能,请将以下内容添加到app/Http/Kernel.php

protected $routeMiddleware = [

...
...

'role' => \sdwru\LaravelFirebaseAuth\Middleware\Role::class,

];

添加用户角色示例

请注意,客户端需要颁发新的令牌以使新角色生效。这可以通过以下三种方式之一根据文档实现:用户登录或重新认证,用户会话在其旧令牌过期后刷新其ID令牌,或在客户端端(JavaScript/Vue/React等)通过调用currentUser.getIdToken(true)强制刷新ID令牌。

<?php

namespace App\Http\Controllers\API;

use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use \Kreait\Firebase\Auth;

class UserController extends Controller
{
  public $auth;
  
  public function __construct(Auth $auth)
  {
      $this->auth = $auth;
  }
   
  public function index(Request $request)
  {
      $users = $this->auth->listUsers($defaultMaxResults = 1000, $defaultBatchSize = 1000);
 
      foreach ($users as $k => $v) {
          $response[$k] = $v;
      }
      echo json_encode($response);
   }
   
   public function update(Request $request, $uid)
   {   
       $this->validate($request, [
           'role' => 'present|string|max:20',
       ]);
       
       $customAttributes = [
         'role' => $request->role,
       ];
       
       $updatedUser = $this->auth->setCustomUserAttributes($uid, $customAttributes);
       
       
       
       return $this->auth->getUser($uid);
   }
}
路由

在Firebase端分配角色后,将其添加到routes/api.php

// Allow any authenticated user
Route::middleware('auth:api')->apiResource('users', 'API\UserController');

// Only allow users with admin and foo roles
Route::middleware('auth:api', 'role:admin, foo')->apiResource('users', 'API\FooController');

// Allow users with admin role only
Route::middleware('auth:api', 'role:admin')->apiResource('users', 'API\AdminController');
角色引用

以下文档中我们分配角色的属性被称为自定义声明。

https://firebase.google.com/docs/auth/admin/custom-claims

https://firebase.google.com/docs/firestore/solutions/role-based-access

https://firebase-php.readthedocs.io/zh/5.x/user-management.html#custom-user-claims

https://www.toptal.com/firebase/role-based-firebase-authentication

支持

欢迎提出问题和提供反馈。