4

我目前正在使用 Laravel Passport 开发多重身份验证,因此该应用程序将拥有用户和设备,当我尝试使用设备注册时,它会将其保存到设备数据库中,如果我尝试登录它会给我 Bearer令牌。但是现在我想通过令牌获取用户中间件'auth:api'或其他方式来获取设备信息,但似乎令牌存储在 oauth_access_token 表和 user_id 中。所以有没有办法让另一个用户 laravel 护照表除了用户?谢谢 ?

这是我的设备代码:

<?php
namespace App;
use Illuminate\Foundation\Auth\User as Authenticatable;

use Illuminate\Notifications\Notifiable;
use Laravel\Passport\HasApiTokens;
use SMartins\PassportMultiauth\HasMultiAuthApiTokens;

class Device extends Authenticatable{


    use Notifiable,HasApiTokens;

   protected $fillable = [
        'name', 'password'  ,
    ];
    /**
     * The attributes that should be hidden for arrays.
     *
     * @var array
     */
    protected $hidden = [
        'password', 'remember_token',
    ];

    /**
     * The attributes that should be cast to native types.
     *
     * @var array
     */
    protected $casts = [
        'email_verified_at' => 'datetime',
    ];


}

设备控制器:

<?php

namespace App\Http\Controllers;

use App\Device;

use Carbon\Carbon;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;

class DeviceController extends Controller{

    //register
    public function signupDevice(Request $request){


        //cant registed with the same email twice
        if(sizeof(Device::where('name','=',$request->query('name'))->get()) > 0)
            return response()->json(['name has already been taken'],500);



        $request->validate([
            'name' => 'required|string',
            'password' => 'required|string|confirmed']);

        $device =new Device(
            [

                'name'=>$request->name,
                'password'=>bcrypt($request->password)

            ]);
        $device->save();
        return response()->json([
            'message' => 'Successfully created device!'
        ], 201);
    }

    public function login(Request $request){

        //validate the data input
        $request->validate([
            'name' => 'required|string',
            'password' => 'required|string',]);


        //attempt returns true if the user is in the database
        $credentials = request(['name', 'password']);
        if(!Auth::guard('device')->attempt($credentials))
            return response()->json([
                'message' => 'Unauthorized'
            ], 401);

        //get the device
        $device = $request->user('device');

        //create token  PAT
        $tokenResult = $device->createToken('Personal Access Token');
        $token = $tokenResult->token;
        if ($request->remember_me)
            $token->expires_at = Carbon::now()->addWeeks(1);


        //save the token
        $token->save();

        return response()->json([
            'access_token' => $tokenResult->accessToken,
            'token_type' => 'Bearer',
            'expires_at' => Carbon::parse(
                $tokenResult->token->expires_at
            )->toDateTimeString()
        ],200);
    }

    public function index(Request $request)
    {

        return response()->json($request->user());
    }


}

路线:

 //routes for device auth
    Route::group(
        [
            'prefix'=>'auth/device'
        ],function ()
        {
            Route::post('signup','DeviceController@signupDevice');
            Route::post('login','DeviceController@login');


         Route::group(
             [
                 'middleware'=>'device'
             ],function(){
              //all the routes that go  throught middleware
             Route::get('index','DeviceController@index');

           });
        });
4

2 回答 2

2

好的,当我自己这样做时,我遇到了障碍:

在数据库中注册的令牌最终可能会出现重复的 user_id,因为您的两个表将具有不同的自动增量值。令牌具有名称属性,因此当具有相同 user_id 的客户(在您的情况下为设备)时,您可以用名称区分它们。

要实现您的要求,您需要声明另一个提供者和另一个守卫。它可以在 config/auth.php 中找到

<?php
    'guards' => [
        'web' => [
            'driver' => 'session',
            'provider' => 'users',
        ],
        'user' => [
            'driver' => 'session',
            'provider' => 'users',
        ],
        'user-api'=>[
            'driver'=>'passport',
            'provider'=>'users',
            'hash'=>false,
        ],
        'customer' => [
            'driver' => 'session',
            'provider' => 'customers',
        ],
        'customer-api'=>[
            'driver'=>'passport',
            'provider'=>'customers',
            'hash'=>false,
        ],

    ],
...
'providers' => [
        'users' => [
            'driver' => 'eloquent',
            'model' => App\Models\User::class,
        ],
        'customers'=>[
            'driver'=>'eloquent',
            'model'=>App\Customer::class,
        ],
    ],
...

新模型需要实现新的属性/类才能使其工作:

use Illuminate\Database\Eloquent\Model;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Laravel\Passport\HasApiTokens;


//
class Customer extends Authenticatable
{
    use HasApiTokens, HasFactory, Notifiable;

    protected $guarded=['id'];
    protected $fillable = [
        /*fillable props*/
    ];
    //
    protected $hidden=[
        /*Hidden props*/
    ];
    //
    protected $casts=[
        /*Your casts*/
    ];

    public function getAuthPassword()
    {
        return $this->password;
    }
}

现在您需要在 App/Providers/RouteServiceProvider 中使用 api 中间件为 http 请求添加前缀:

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

        $this->routes(function () {
            Route::prefix('api')
                ->middleware('api')
                ->group(base_path('routes/api.php'));
    }

然后,当您声明一条路线时,将新的身份验证中间件保护与您声明的护照驱动程序一起使用:

Route::group( ['prefix' => 'customer','middleware' => ['auth:customer-api'] ],function(){

/*Authenticated staff route here*/

});  

当您登录时,您应该使用 auth 保护和会话驱动程序:

public function customerLogin(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'email' => 'required|email',
            'password' => 'required',
        ]);

        if($validator->fails()){
            return response()->json(['error' => $validator->errors()->all()]);
        }

        if(auth()->guard('customer')->attempt(['email' => request('email'), 'password' => request('password')])){
            config(['auth.guards.api.provider' => 'customer']);
  
            $customer = Customer::select('customers.*')->find(auth()->guard('customer')->user()->id);
            $success =  $customer;
            $success['token'] =  $customer->createToken('Customer'.$customer->name,['customer'])->accessToken; 

            return response()->json($success, 200);
        }else{ 
            return response()->json(['error' => ['Email and Password are Wrong.']], 200);
        }
    } 

这里是不同认证的token输出表数据

  

  {
        "id": "2a8526b24bd89a47f29474a86ba350c843cd4f7c5b0785c34d908efe00a4715c43502dbd9f789b83",
        "user_id": "19",
        "client_id": "15",
        "name": "user;SuperAdmin",
        "scopes": "[\"user\"]",
        "revoked": "0",
        "created_at": "2021-02-24 02:10:31",
        "updated_at": "2021-02-24 02:10:31",
        "expires_at": "2021-02-25 02:10:31"
    },
    {
        "id": "388792d1c191529c65f1fb67d58972d2b26aae19d99c8df1c2321ec100bedff96a38b7724626f1cb",
        "user_id": "53",
        "client_id": "15",
        "name": "Customer;1First.1Last@example.com",
        "scopes": "[\"customer\"]",
        "revoked": "0",
        "created_at": "2021-02-24 02:10:28",
        "updated_at": "2021-02-24 02:10:28",
        "expires_at": "2021-02-25 02:10:28"
    }

我没有包括范围。但请注意,如果您想限制路由访问,您应该实施它们。

于 2021-02-24T02:17:46.483 回答
-2

例如,如果您的表名是 tbl_user,那么您应该如下创建模型并在 config/auth.php 中添加模型路径

Model:
<?php

namespace App\model\Users;

use Illuminate\Database\Eloquent\Model;
use Laravel\Passport\HasApiTokens;
use Illuminate\Notifications\Notifiable;
use Illuminate\Foundation\Auth\User as Authenticatable;

class UserModel extends Authenticatable
{
    use HasApiTokens, Notifiable;
    protected $table = 'tbl_user';
    public $timestamps = false;

}


config/auth.php
'providers' => [
        'users' => [
            'driver' => 'eloquent',
            'model' => App\model\Users\UserModel::class,
        ],
    ],
于 2019-12-16T12:51:04.310 回答