laravel+dingo+jwt+laravel-core

laravel+dingo+jwt+laravel-core

1、安装laravel5.8

composer create-project --prefer-dist laravel/laravel blog "5.8.*"

2、安装dinggo

"require": {
    "dingo/api": "^2.2"
}

然后执行

composer update

2.1、配置dingo

使用以下命令可以发布 API 的配置文件到 config 文件下:

php artisan vendor:publish --provider="Dingo\Api\Provider\LaravelServiceProvider"

.env的配置直接贴出来,以做参考

API_STANDARDS_TREE=prs
API_SUBTYPE=mdCalendar
API_PREFIX=api
API_VERSION=v1
API_DEBUG=true

######这里再给个较为完整的
#以下是我的配置:
API_STANDARDS_TREE=vnd
API_SUBTYPE=laravel
API_PREFIX=api
#子域名 (前缀和子域名只能存在一个)可选
#API_DOMAIN=api.myapp.com
API_VERSION=v1
API_NAME=api-demo
#API_CONDITIONAL_REQUEST=false
#API_STRICT=false
API_DEFAULT_FORMAT=json
API_DEBUG=true

2.2配置文件 config/app.php

"providers"=>[
    ...
    // Dingo
    Dingo\Api\Provider\LaravelServiceProvider::class,
],

2.3最后是创建端点,也就是路由的创建,需要按照dingo的格式(方式)来创建,因为dingo已经接管了路由,我贴出一个最终的路由,以做参考(这里不解释中间件的意义)

// 创建路由对象
$api = app('Dingo\Api\Routing\Router');
// 配置版本 中间件  命名空间
$api->version('v1', ['namespace' => 'App\Http\Controllers\Api\v1'], function ($api) {
    // 这是个登录的格式  也可以指定name值(即别名)
    $api->post('login', 'LoginController@login')->name('api.login');
    // 在这里可以使用分组   分组里也可以指定中间件  
    $api->group(['middleware' => 'auth:api'], function ($api) {
        $api->post('logout', 'LoginController@logout');
    });
});

3、安装JWt

composer require tymon/jwt-auth

生成 JWT_SECRET 写入.env(自动写入)
php artisan jwt:secret

3.1配置文件 config/app.php

//在 providers 数组中添加以下两个服务提供者:
    
"providers"=>[
    ...
    Tymon\JWTAuth\Providers\LaravelServiceProvider::class,
],
    
//在 aliases 数组中给 JWT 以下两个类添加别名方便之后生成 token 时使用,(当然也可以使用 Auth 门面生成 token , 所以不添加也是可以的。) 
    
'aliases' => [
    ...
    'JWTAuth' => Tymon\JWTAuth\Facades\JWTAuth::class,
    'JWTFactory' => Tymon\JWTAuth\Facades\JWTFactory::class,
]

3.2生成 Dingo 和 JWT 的配置文件

php artisan vendor:publish --provider="Tymon\JWTAuth\Providers\LaravelServiceProvider"  //生成 JWT 的 jwt.php 文件
【 实际上是 vendor/tymon/jwt-auth/config/config.php 这个配置文件 】

3.3修改 api.php 和 jwt.php 配置文件(将dingo与jwt结合起来)

//在 api.php 的 auth 数组中添加 api 权限验证类

'auth' => [
    'jwt' => Dingo\Api\Auth\Provider\JWT::class,  // api 权限验证类
],

//把 jwt.php providers 数组中的 token 生成类(Lcobucci)修改为 Namshi 如下:

'providers' => [
    //'jwt' => Tymon\JWTAuth\Providers\JWT\Lcobucci::class, // 使用 attempt() 方法生成 token (本人不推荐使用这方法)
    
    'jwt' => Tymon\JWTAuth\Providers\JWT\Namshi::class, //使用 formUser() 方法生成 token  
    
    .
    .

3.4修改 config/auth.php 配置文件

'defaults' => [
        'guard' => 'web',   // 默认 web  可以改成api,也可以保持默认,由需求决定
                            // 若既做api,又做web,那么建议保持默认即可,只是后续用到的Auth认证
                            // 时需要指定guard('api'或者'web') 指定api或者web
        'passwords' => 'users',
    ],

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

        'api' => [
            'driver' => 'jwt', //原来为 token
            'provider' => 'users',
            'hash' => false,
        ],
    ],
'providers' => [
        'users' => [
            'driver' => 'eloquent',
            // 这里注意改成自己对应的用户模型类  主要注意命名空间
            'model' => App\Models\Users::class,
        ],

        // 'users' => [
        //     'driver' => 'database',
        //     'table' => 'users',
        // ],
    ],

3.5调整Users模型

<?php

namespace App\Models;

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

class Users extends Authenticatable implements JWTSubject
{
    use  Notifiable,SoftDeletes;

    public $table = 'users';

    // const CREATED_AT = 'created_at';
    // const UPDATED_AT = 'updated_at';

    
    //设置添加的字段   create 添加数据有效
    //黑名单  拒绝哪些字段不能被添加的
    protected $guarded=[];
    //指定软删除标识字段
    protected $dates=['deleted_at'];
    /**
     * The attributes that should be hidden for arrays.
     *
     * @var array
     */
    protected $hidden = [
        'password',
    ];


    //实现 JWTSubject 以下两个接口函数
    public function getJWTIdentifier()
    {
        return $this->getKey();
    }

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

3.6创建基础控制器,目的是为了格式化(或者叫统一)响应数据的格式(这个不是必须的步骤)

<?php

namespace App\Http\Controllers\Api\v1;

use App\Http\Controllers\Controller;
use Dingo\Api\Routing\Helpers;

class BaseController extends Controller
{
    // 接口帮助调用
    use Helpers;

    // 工具函数
    // 返回错误的请求
    protected function errorBadRequest($validator)
    {
        //throw new ValidationHttpException($validator->errors());
        $result = [];
        $messages = $validator->errors()->toArray();
        if ($messages) {
            foreach ($messages as $field => $errors) {
                foreach ($errors as $error) {
                    $result[] = [
                        'field' => $field,
                        'code' => $error,
                    ];
                }
            }
        }
        $this->responseValidationError($result);
    }

    // 请求成功时对数据进行格式处理
    public function responseSuccess($msg, $data = null)
    {
        return response()->json([
            'code' => '200',
            'msg' => $msg,
            'data' => $data
        ]);
    }

    // 响应失败时返回自定义错误信息
    public function responseError($msg)
    {
        return response()->json([
            'code' => '400',
            'msg' => $msg
        ]);
    }

    // 响应校验失败时返回自定义的信息(基本用不上)
    public function responseValidationError($msgs)
    {
        return response()->json([
            'code' => '401',
            'msgs' => $msgs
        ]);
    }

    // 错误提示方法
    public function onError($msgs)
    {
        return response()->json([
            'code' => 'error',
            'msgs' => $msgs
        ]);
    }

    protected function respondWithToken($token, $data)
    {
        return response()->json([
            'data' => $data,
            'access_token' => $token,
            'token_type' => 'bearer'
        ]);
    }
}

3.7、创建登录用的控制器(登录控制器的注意命名空间)

<?php

namespace App\Http\Controllers\Api\v1;

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Exception;
use Illuminate\Contracts\Auth\Guard;
use Illuminate\Hashing\BcryptHasher;
use JWTAuth;

class LoginController extends BaseController
{
    public function login()
    {
        $credentials = request(['username', 'password']);
        // return ['msg' => 11];
        if (!$token = auth()->guard('api')->attempt($credentials)) {
            return response()->json(['error' => 'Unauthorized'], 401);
        }
        return $this->respondWithToken($token, auth('api')->user());
    }
    public function logout(Request $request)
    {
        auth()->guard('api')->logout();
        return $this->responseSuccess('退出成功');
    }
}

4、安装laravel-cors

"require": {
        "fruitcake/laravel-cors": "^2.0"
    },

之后执行composer  update就行了

4.1全局注册其中间件(有些博客说是可以注册到路由中间件,其实是不可以的,最后会贴出具体解释)

protected $middleware = [
  \Fruitcake\Cors\HandleCors::class,
    // ...
];

4.2执行下面的命令自动创建配置文件

php artisan vendor:publish --tag="cors"

4.3查看配置文件cors.php(我这里就直接保持默认了)

<?php

return [
    /*
     * You can enable CORS for 1 or multiple paths.
     * Example: ['api/*']
     */
    'paths' => ['api/*'],

    /*
    * Matches the request method. `[*]` allows all methods.
    */
    'allowed_methods' => ['*'],

    /*
     * Matches the request origin. `[*]` allows all origins. Wildcards can be used, eg `*.mydomain.com`
     */
    'allowed_origins' => ['*'],

    /*
     * Patterns that can be used with `preg_match` to match the origin.
     */
    'allowed_origins_patterns' => [],

    /*
     * Sets the Access-Control-Allow-Headers response header. `[*]` allows all headers.
     */
    'allowed_headers' => ['*'],

    /*
     * Sets the Access-Control-Expose-Headers response header with these headers.
     */
    'exposed_headers' => false,

    /*
     * Sets the Access-Control-Max-Age response header when > 0.
     */
    'max_age' => 0,

    /*
     * Sets the Access-Control-Allow-Credentials header.
     */
    'supports_credentials' => false,
];

5、最后来看一下路由

// 创建路由对象
$api = app('Dingo\Api\Routing\Router');
// 配置版本 中间件  命名空间
$api->version('v1', ['namespace' => 'App\Http\Controllers\Api\v1'], function ($api) {
    // 这是个登录的格式  也可以指定name值(即别名)
    $api->post('login', 'LoginController@login')->name('api.login');
    // 在这里可以使用分组   分组里也可以指定中间件  'auth:api' 是jwt提供的,直接就这么写就可以
    $api->group(['middleware' => 'auth:api'], function ($api) {
        $api->post('logout', 'LoginController@logout');
    });
});

最后看一下结果:

 

 完美解决!

最后再说一下为什么不建议或者不可以使用laravel-cors注册为路由或路由分组中间件(因为官方没说可以)

 

 附上链接:https://packagist.org/packages/barryvdh/laravel-cors#v2.0.1

参考链接:https://blog.csdn.net/chenlevin/article/details/111687928(注意他的版本,我们的版本是5.8)

posted @ 2021-02-24 18:19  养猪至富  阅读(266)  评论(0编辑  收藏  举报