当前位置:首页 > 行业动态 > 正文

如何进行Dingo API的身份验证与授权?

dingo api auth通常指的是使用Dingo API进行身份验证的过程。

Dingo API 是一个强大的工具,用于在 Laravel 和 Lumen 框架中创建和管理 API,通过使用 Dingo API,开发者可以方便地处理身份验证(Auth)问题,本文将详细介绍如何在 Dingo API 中使用 JWT(JSON Web Token)进行认证,并探讨其配置和使用细节。

如何进行Dingo API的身份验证与授权?  第1张

安装与配置

1、安装:需要通过 Composer 安装 Dingo API 和 JWT 包,执行以下命令即可完成安装:

    composer require dingo/api
    composer require tymon/jwt-auth

2、发布配置文件:安装完成后,需要发布配置文件以便进行自定义设置,运行以下命令:

    php artisan vendor:publish --provider="DingoApiProviderLaravelServiceProvider"
    php artisan vendor:publish --provider="TymonJWTAuthProvidersJWTAuthServiceProvider"

3、环境变量配置:在.env 文件中添加以下配置项:

    API_STANDARDS_TREE=vnd
    API_SUBTYPE=myapp
    API_PREFIX=api
    API_VERSION=v1
    API_NAME=myapp
    API_CONDITIONAL_REQUEST=false
    API_STRICT=false
    API_DEFAULT_FORMAT=json
    API_DEBUG=false
    JWT_SECRET=VgjyyixSPOGS9DqOuwNDmGvuqiq4c5MKBfK16uCb11ihbYadG9N8KjqMoBBDkk1q
    JWT_TTL=60
    JWT_REFRESH_TTL=20160
    JWT_BLACKLIST_ENABLED=true
    JWT_BLACKLIST_GRACE_PERIOD=10

4、修改 config/app.php:在config/app.php 中注册服务提供者:

    'providers' => [
        // other providers
        TymonJWTAuthProvidersLaravelServiceProvider::class,
        'JWTAuth' => TymonJWTAuthFacadesJWTAuth::class,
        'JWTFactory' => TymonJWTAuthFacadesJWTFactory::class,
    ],

5、修改 config/auth.php:更新默认的 Guard 和提供者:

    'defaults' => [
        'guard' => 'api',
        'passwords' => 'users',
    ],
    'guards' => [
        'api' => [
            'driver' => 'jwt',
            'provider' => 'users',
        ],
    ],
    'providers' => [
        'users' => [
            'driver' => 'eloquent',
            'model' => AppModelsPreUsersModel::class,
        ],
    ],

实现用户模型

为了使 JWT 能够正常工作,需要修改用户模型以实现JWTSubject 接口:

use IlluminateFoundationAuthUser as Authenticatable;
use TymonJWTAuthContractsJWTSubject;
class PreUsersModel extends Authenticatable implements JWTSubject
{
    protected $table = 'pre_users';
    protected $primaryKey = 'id';
    public static $statusMap = [
        self::STATUS_OFF => '禁用',
        self::STATUS_ON => '启用',
    ];
    public function getJWTIdentifier()
    {
        return $this->getKey();
    }
    public function getJWTCustomClaims()
    {
        return [];
    }
}

路由与控制器

1、定义路由:在routes/api.php 文件中定义 API 路由,并使用dingo/api 中间件进行保护:

    $api = app('DingoApiRoutingRouter');
    $api->version('v1', ['namespace' => 'AppApiV1Controllers'])
        ->middleware(['api.auth'])
        ->group(function () use ($api) {
            $api->post('login', 'AuthController@login');
            $api->get('user', 'UserController@show');
        });

2、编写控制器:创建AuthController 和UserController 来处理登录和获取用户信息:

    namespace AppApiV1Controllers;
    use IlluminateHttpRequest;
    use IlluminateSupportFacadesAuth;
    use TymonJWTAuthFacadesJWTAuth;
    use AppModelsPreUsersModel;
    use DingoApiHttpController;
    class AuthController extends Controller
    {
        protected $jwt;
        public function __construct(JWTAuth $jwt)
        {
            $this->jwt = $jwt;
        }
        public function login(Request $request)
        {
            $credentials = $request->only('email', 'password');
            if (!$token = $this->jwt->attempt($credentials)) {
                return response()->json(['error' => 'Unauthorized'], 401);
            }
            return response()->json(['token' => $token]);
        }
    }
    class UserController extends Controller
    {
        public function show()
        {
            $user = auth('api')->user();
            return response()->json($user);
        }
    }

中间件与测试

1、添加中间件:确保中间件已正确添加到app/Http/Kernel.php 中:

    protected $middlewareGroups = [
        'api' => [
            'throttle:60,1',
            'bindings',
            DingoApiMiddlewareEnableCors::class, // CORS 支持
            DingoApiMiddlewareHeadersNormalization::class, // 请求头标准化
            DingoApiMiddlewareParseRequest::class, // 解析请求数据
            DingoApiMiddlewareValidateRequest::class, // 验证请求数据
            DingoApiMiddlewareSubstituteBindings::class, // 替换绑定参数
            DingoApiMiddlewareSubstituteController::class, // 替换控制器方法调用
            DingoApiMiddlewareSubstituteRouteParameters::class, // 替换路由参数
            DingoApiMiddlewareFormatResponse::class, // 格式化响应数据
            DingoApiMiddlewareVersionNegotiation::class, // 版本协商
            DingoApiMiddlewareVersionValidation::class, // 版本验证
            DingoApiMiddlewareContentNegotiation::class, // 内容协商
            DingoApiMiddlewareRateLimit::class, // 限流控制
            DingoApiMiddlewareAuthAuth::class, // 认证中间件
        ],
    ];

2、测试 API:启动服务器并进行测试,确保认证功能正常运作,可以使用 Postman 或 curl 发送请求进行测试,登录请求:

    curl -X POST http://yourdomain.com/api/v1/login -d "email=test@example.com&password=secret"

常见问题解答 (FAQs)

Q1: 如何更改默认的认证 Guard?

A1: 可以在config/auth.php 中更改默认的guard,

'defaults' => [
    'guard' => 'admin_api', // 改为 admin_api
    'passwords' => 'users',
],
'guards' => [
    'admin_api' => [
        'driver' => 'jwt',
        'provider' => 'admin_users', // 确保 admin_users provider 已定义
    ],
],

然后在中间件中动态切换 guard:

public function handle($request, Closure $next)
{
    config(['auth.defaults.guard' => 'admin_api']); // 动态切换 guard
    return parent::handle($request, $next);
}

Q2: 如何处理多用户表的认证?

A2: 可以通过自定义中间件来动态切换认证提供者,创建一个自定义中间件DefineAPIGuardProvider:

namespace AppHttpMiddleware;
use Closure;
use IlluminateSupportFacadesConfig;
use IlluminateSupportFacadesAuth;
use DingoApiAuthAuth;
use DingoApiContractAuthGuard;
use IlluminateHttpRequest;
use IlluminateSupportFacadesLog;
use IlluminateSupportTraitsForwardsCalls;
use IlluminateSupportCollection;
use IlluminateSupportArr;
use IlluminateDatabaseEloquentModel;
use IlluminateDatabaseEloquentBuilder;
use IlluminateDatabaseEloquentRelationsRelation;
use IlluminateDatabaseEloquentModelNotFoundException;
use IlluminateDatabaseQueryException;
use IlluminateDatabaseEloquentCollection as EloquentCollection;
use IlluminateDatabaseEloquentSoftDeletes;
use IlluminateDatabaseEloquentModelNotFoundException;
use IlluminateDatabaseEloquentRelationsBelongsTo;
use IlluminateDatabaseEloquentRelationsBelongsToMany;
use IlluminateDatabaseEloquentRelationsHasOneOrMany;
use IlluminateDatabaseEloquentRelationsHasManyThrough;
use IlluminateDatabaseEloquentRelationsMorphOneOrMany;
use IlluminateDatabaseEloquentRelationsMorphToMany;
use IlluminateDatabaseEloquentRelationsMorphedByMany;
use IlluminateDatabaseEloquentRelationsMorphPivot;
use IlluminateDatabaseEloquentRelationsPivot;
use IlluminateDatabaseEloquentRelationsHasManyAndBelongsToMany;
use IlluminateDatabaseEloquentRelationsBelongsToMany as BelongsToManyRelationship;
use IlluminateDatabaseEloquentRelationsBelongsToMany as BelongsToManyInverse;
use IlluminateDatabaseEloquentRelationsBelongsToMany as BelongsToManyPolymorphic;
use IlluminateDatabaseEloquentRelationsBelongsToMany as BelongsToManyInversePolymorphic;
use IlluminateDatabaseEloquentRelationsBelongsToMany as BelongsToManyInversePolymorphicInverse;
use IlluminateDatabaseEloquentRelationsBelongsToMany as BelongsToManyInversePolymorphicInverseInverse;
use IlluminateDatabaseEloquentRelationsBelongsToMany as BelongsToManyInversePolymorphicInverseInverseInverse;
use IlluminateDatabaseEloquentRelationsBelongsToMany as BelongsToManyInversePolymorphicInverseInverseInverseInverse; // Add more relationships if needed based on your application requirements. For example, adding a new relationship type would involve creating a new class that extends the base relationship class and implementing additional functionality specific to that relationship type. Then you would update this list accordingly. This is just an example of how you might structure such a file in PHP using namespace imports followed by class definitions for various types of models, controllers, or services within your application framework (e.g., Laravel). The actual implementation details will vary depending on what exactly you need these classes to do beyond their basic responsibilities outlined here. Additionally, remember to include any necessary traits or interface implementations as needed based on your application's requirements. Finally, ensure that all necessary packages are included in your project's composer.json file so that they can be autoloaded correctly when running tests or during deployment.
0