zoukankan      html  css  js  c++  java
  • 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="DingoApiProviderLaravelServiceProvider"

    .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
        DingoApiProviderLaravelServiceProvider::class,
    ],

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

    // 创建路由对象
    $api = app('DingoApiRoutingRouter');
    // 配置版本 中间件  命名空间
    $api->version('v1', ['namespace' => 'AppHttpControllersApiv1'], 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"=>[
        ...
        TymonJWTAuthProvidersLaravelServiceProvider::class,
    ],
        
    //在 aliases 数组中给 JWT 以下两个类添加别名方便之后生成 token 时使用,(当然也可以使用 Auth 门面生成 token , 所以不添加也是可以的。) 
        
    'aliases' => [
        ...
        'JWTAuth' => TymonJWTAuthFacadesJWTAuth::class,
        'JWTFactory' => TymonJWTAuthFacadesJWTFactory::class,
    ]

    3.2生成 Dingo 和 JWT 的配置文件

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

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

    //在 api.php 的 auth 数组中添加 api 权限验证类
    
    'auth' => [
        'jwt' => DingoApiAuthProviderJWT::class,  // api 权限验证类
    ],
    
    //把 jwt.php providers 数组中的 token 生成类(Lcobucci)修改为 Namshi 如下:
    
    'providers' => [
        //'jwt' => TymonJWTAuthProvidersJWTLcobucci::class, // 使用 attempt() 方法生成 token (本人不推荐使用这方法)
        
        'jwt' => TymonJWTAuthProvidersJWTNamshi::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' => AppModelsUsers::class,
            ],
    
            // 'users' => [
            //     'driver' => 'database',
            //     'table' => 'users',
            // ],
        ],

    3.5调整Users模型

    <?php
    
    namespace AppModels;
    
    use IlluminateFoundationAuthUser as Authenticatable;
    use IlluminateNotificationsNotifiable;
    use IlluminateDatabaseEloquentSoftDeletes;
    use TymonJWTAuthContractsJWTSubject;
    
    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 AppHttpControllersApiv1;
    
    use AppHttpControllersController;
    use DingoApiRoutingHelpers;
    
    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 AppHttpControllersApiv1;
    
    use IlluminateHttpRequest;
    use IlluminateSupportFacadesAuth;
    use Exception;
    use IlluminateContractsAuthGuard;
    use IlluminateHashingBcryptHasher;
    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 = [
      FruitcakeCorsHandleCors::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('DingoApiRoutingRouter');
    // 配置版本 中间件  命名空间
    $api->version('v1', ['namespace' => 'AppHttpControllersApiv1'], 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)

  • 相关阅读:
    h5页面页面在iphoneX手机上底部会有留白解决办法
    自定义单张图片放大预览功能,可支持手势缩放,依赖jquery
    js事件内部有click事件时,click事件会重复调用解决方法
    h5页面通过阿里云的broswer-js-sdk上传文件
    python字符串前加r、f、u、l 的区别
    Python基础面试题 :计算列表中出现最多次的字符
    python基础入门教程:传参是传值还是传引用
    Python 面试题:输入一个数组,输出该数组的第二大的数字
    Python 7种超实用的数据清洗方法,这你一定要掌握
    python教程:3个非常有用的内置函数(filter/map/reduce)
  • 原文地址:https://www.cnblogs.com/zqblog1314/p/14443054.html
Copyright © 2011-2022 走看看