前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >laravel 中配置DingoApi 和JWT

laravel 中配置DingoApi 和JWT

作者头像
友儿
发布2023-10-21 13:55:51
2290
发布2023-10-21 13:55:51
举报
文章被收录于专栏:友儿

laravel 相关

安装 laravel 框架,版本根据自己的实际情况选择

代码语言:javascript
复制
composer create-project --prefer-dist laravel/laravel laravel "8.5.*"

.env文件中配置数据库连接

代码语言:javascript
复制
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=laravel
DB_USERNAME=root
DB_PASSWORD=De5RJZWSjJF42FkC

数据库迁移

代码语言:javascript
复制
# 在项目根目录执行
php artisan migrate

数据填充

填充前准备

DatabaseSeeder.png
DatabaseSeeder.png

执行填充

代码语言:javascript
复制
php artisan db:seed

Dingo Api 相关

安装 Dingo Api

代码语言:javascript
复制
composer require "dingo/api"

在 config 目录生成配置文件api.php

代码语言:javascript
复制
php artisan vendor:publish --provider="Dingo\Api\Provider\LaravelServiceProvider"

.env文件里配置Dingo Api , Dingo API 配置项说明

代码语言:javascript
复制
# dingo api
API_STANDARDS_TREE=x            // 环境
API_SUBTYPE=myapp               // 子类型
API_PREFIX=api                  // 前缀
API_DOMAIN=api.myapp.com        // 域名
API_VERSION=v1                  // 版本号
API_NAME="My API"               // 名字
API_CONDITIONAL_REQUEST=false   // 条件请求
API_STRICT=false                // 严格模式
API_DEFAULT_FORMAT=json         // 响应格式
API_DEBUG=true                  // 调试模式

JWT 相关

安装 jwt-auth ,参考文档 jwt-auth 文档

代码语言:javascript
复制
composer require "tymon/jwt-auth"

在 config 目录生成配置文件jwt.php

代码语言:javascript
复制
php artisan vendor:publish --provider="Tymon\JWTAuth\Providers\LaravelServiceProvider"

.env中生成加密所需字符串 JWT_SECRET

代码语言:javascript
复制
php artisan jwt:secret

修改你的 app/Models/User.php

代码语言:javascript
复制
<?php

namespace App\Models;

use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Tymon\JWTAuth\Contracts\JWTSubject;

class User extends Authenticatable implements JWTSubject
{
  use HasFactory, Notifiable;

  /**
   * The attributes that are mass assignable.
   *
   * @var array
   */
  protected $fillable = [
      'name',
      'email',
      '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',
  ];

  public function getJWTIdentifier()
  {
      return $this->getKey();
  }

  public function getJWTCustomClaims()
  {
      return [];
  }
}

修改 config/auth.php

代码语言:javascript
复制

'defaults' => [
  'guard' => 'api',
  'passwords' => 'users',
],

...

'guards' => [
  'api' => [
      'driver' => 'jwt',
      'provider' => 'users',
  ],
],

修改 routes/api.php , 由Dingo 接管

代码语言:javascript
复制
<?php

$api = app('Dingo\Api\Routing\Router');

$api->version('v1', ['namespace' => 'App\Http\Controllers\Api\v1'], function ($api) {
  $api->get('password', 'AuthController@password')->name('password');
  $api->post('login', 'AuthController@login')->name('login');
  $api->group(['middleware' => 'api.auth'], function ($api) {
      $api->post('logout', 'AuthController@logout');
      $api->post('refresh', 'AuthController@refresh');
      $api->post('me', 'AuthController@me')->name('me');
  });
});

创建 基础控制器、用户认证控制器,对应路由文件中的命名空间 App\Http\Controllers\Api\v1

Controller

代码语言:javascript
复制
<?php
namespace App\Http\Controllers\Api\V1;

use Dingo\Api\Routing\Helpers;
use Illuminate\Routing\Controller as BaseController;

class Controller extends BaseController
{
use Helpers;
}

AuthController

代码语言:javascript
复制
<?php

namespace App\Http\Controllers\Api\V1;

use App\Models\User;

class AuthController extends Controller
{
public function password()
{
    $password = bcrypt('123456');
    User::find(1)->update(['password' => $password]);
    return response()->json(['password' => 123456]);
}
/**
 * Get a JWT via given credentials.
 *
 * @return \Illuminate\Http\JsonResponse
 */
public function login()
{
    $credentials = request(['email', 'password']);

    if (! $token = auth()->attempt($credentials)) {
        return response()->json(['error' => 'Unauthorized'], 401);
    }

    return $this->respondWithToken($token);
}

/**
 * Get the authenticated User.
 *
 * @return \Illuminate\Http\JsonResponse
 */
public function me()
{
    return response()->json(auth()->user());
}

/**
 * Log the user out (Invalidate the token).
 *
 * @return \Illuminate\Http\JsonResponse
 */
public function logout()
{
    auth()->logout();

    return response()->json(['message' => 'Successfully logged out']);
}

/**
 * Refresh a token.
 *
 * @return \Illuminate\Http\JsonResponse
 */
public function refresh()
{
    return $this->respondWithToken(auth()->refresh());
}

/**
 * Get the token array structure.
 *
 * @param  string $token
 *
 * @return \Illuminate\Http\JsonResponse
 */
protected function respondWithToken($token)
{
    return response()->json([
        'access_token' => $token,
        'token_type' => 'bearer',
        'expires_in' => auth()->factory()->getTTL() * 60
    ]);
}
}

配置 Dongo API 的Auth认证使用JWT

config/api.php

代码语言:javascript
复制
  'auth' => [
      'jwt' => 'Dingo\Api\Auth\Provider\JWT',
  ],

认证测试

  • 密码错误时
auth.png
auth.png
  • 更新并获取数据库ID=1的密码用于测试
password.png
password.png
  • 用正确的密码尝试获取access_token
access_token.png
access_token.png
  • access_token 获取用户信息
user.png
user.png

当你不想使用默认的email 作为用户名时

editParams.png
editParams.png
  • 测试
name.png
name.png

访问节流限制

Dingo API 默认节流限速是绑定客户 ip 地址的。如果需要自定义节流限速方法,需要注册你自己的解决者。

新建 app/Http/Middleware/MyThrottle.php, 例如我这里以openid为标识节流限速

代码语言:javascript
复制
<?php

namespace App\Http\Middleware;

use Dingo\Api\Contract\Http\RateLimit\HasRateLimiter;
use Dingo\Api\Http\RateLimit\Throttle\Throttle;
use Dingo\Api\Http\Request;
use Illuminate\Container\Container;

class MyThrottle extends Throttle implements HasRateLimiter
{
  /**
   * @param Container $container
   * @return bool
   */
  public function match(Container $container): bool
  {
      return $container['api.auth']->check();
  }

  public function getRateLimiter(Container $app, Request $request): string
  {
      $user = auth()->user();
      return $user->openid;    
  }
}

在 routes/api.php 使用

代码语言:javascript
复制
<?php

use App\Http\Middleware\MyThrottle;

$api = app('Dingo\Api\Routing\Router');

$api->version('v1', ['namespace' => 'App\Http\Controllers\Api\v1'], function ($api) {
  $api->group(['middleware' => 'api.auth'], function ($api) {
      $api->get('limit', [
          'middleware' => 'api.throttle',
          'throttle' => new MyThrottle(['limit' => 1, 'expires' => 1]), //一分钟一次请求
          'uses' => 'AuthController@limit'
      ])->name('limit');
  });
});

测试

  • 同一分钟请求第一次
limit-pass.png
limit-pass.png
  • 同一分钟请求第二次
limit-err.png
limit-err.png

当然你如果认为Dingdo APi 抛出的异常不美观,你也可以捕获 Dongo API 错误进行自定义配置

  • 首先在 app/Exceptions/Dingo.php 文件用于处理自定义
代码语言:javascript
复制
<?php

<?php

namespace App\Exceptions;

use Exception;
use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;

class Dingo extends ExceptionHandler
{
  /**
   * Render an exception into an HTTP response.
   *
   * @param  \Illuminate\Http\Request  $request
   * @param  \Exception  $exception
   * @return \Illuminate\Http\Response
   */
  public function render($request, Exception|\Throwable $exception)
  {
      if (get_class($exception) == 'Dingo\Api\Exception\RateLimitExceededException') {
          return response()->json([
              'message' => '请勿频繁提交!!'
          ],429);
      }
      return parent::render($request, $exception);
  }
}
  • app/Providers/AppServiceProvider.php 中注册服务
代码语言:javascript
复制
<?php

namespace App\Providers;

use Illuminate\Http\Request;
use Illuminate\Support\ServiceProvider;

class AppServiceProvider extends ServiceProvider
{
  /**
   * Register any application services.
   *
   * @return void
   */
  public function register()
  {
      //
  }

  /**
   * Bootstrap any application services.
   *
   * @return void
   */
  public function boot()
  {
      app('api.exception')->register(function (\Exception $exception) {
          return app('App\Exceptions\Dingo')->render(
              Request::capture(),
              $exception
          );
      });
  }
}
error.png
error.png
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • laravel 相关
  • Dingo Api 相关
  • JWT 相关
  • 配置 Dongo API 的Auth认证使用JWT
  • 认证测试
  • 当你不想使用默认的email 作为用户名时
  • 访问节流限制
相关产品与服务
腾讯云服务器利旧
云服务器(Cloud Virtual Machine,CVM)提供安全可靠的弹性计算服务。 您可以实时扩展或缩减计算资源,适应变化的业务需求,并只需按实际使用的资源计费。使用 CVM 可以极大降低您的软硬件采购成本,简化 IT 运维工作。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档