美文网首页
1-2 8章前结束

1-2 8章前结束

作者: 这个超人不会飞阿 | 来源:发表于2018-05-02 16:14 被阅读55次

    9.1 令牌.
    之前我们做的所有接口都没有权限控制,所有用户都可以调用.
    但是有些接口能公开访问.有些接口就不能公开访问.这个权限怎么做?
    我们是用令牌管理我们的用户身份的.登录就是获取一个令牌.用户在每一次api请求都需要携带它的令牌.
    下面我们逐步学习令牌的设计以及原理.


    1.令牌

    上面的流程是一个通用的设计模式.


    2.image.png
    Auth代表身份 Token也有过期时间 不是有Token就能获取下单接口,还有验证身份..........
    (1)验证Token是否合法
    (2)验证是否Token有效(过期没)
    (3)验证Token所对应的权限

    9.2 微信体系身份设计
    上节是将的基础,思路,这一节是对上面的细化

    3.对图片2的延伸
    因为小程序会为每一个用户生成一个Code码,因此不再需要传递账户,密码.只需将Code码传递给getToken,
    在getToken方法中我们需要将Code码传递到微信服务器中,服务器会返回你2个重要的信息(openid,session_key),openid就是用户唯一的标识,不过还有别的用处,比如微信支付时候.在我们这里不需要使用session_key.同一个用户在不同的小程序内部openid是不同的.
    在getToken方法下拿到Token,然后将Token存起来.于是用户身份体系就建立起来了.
    然后将Token返回给客户端,让客户端每次访问都携带Token.
    不建议将openid传入到客户端,因为openid安全的原因,还有openid不能改变.就不能设置它的有效期.解决方法就是生成一个令牌.
    缓存实际上将Token和用户信息存储在缓存中,加快访问速度.但是不要滥用缓存.虽然缓存用起来的非常简单的,但是缓存的维护是非常麻烦的.这个远远要比数据库的维护还要麻烦.
    4.image.png
    缓存的好处是不用去查数据库了,直接去缓存内校验Token

    9.3 开始实现Token身份权限体系
    route.php

    //获取Token  为什么这里要用post 因为code安全性 get参数只能放在url路径下,因此用post将参数放到body里面去.比get要好一点.但是使用抓包工具还是能查看到相应的信息.因此最安全的是https
    Route::post('api/:version/token/user','api/:version.Token/getToken');
    

    因为开始编写User模型业务逻辑就开始更加麻烦,因此我们再写一个service层.
    service层很好的体现了MVC的Model层的分层概念.Service就是处理较为复杂的业务逻辑.而Model只是处理一些细粒度的单个业务逻辑.Model层不仅编写简单的业务逻辑,而且对数据库操作.实现数据表的增删改查.
    Model模型定义的名字必须与数据库的表名相一致!

    9.3.1 编写Token
    控制层Token.php

    class Token
    {
        //code是小程序用户都会拥有的
        public function getToken($code=''){
            //校验参数 去目录validate
            //编写路由
            (new TokenGet())->goCheck();
            $ut = new UserToken();
            $token = $ut->get($code);
            return $token;
        }
    }
    

    模型层User.php

    class User extends BaseModel
    {
    
    }
    

    Service层下UserToken.php

    
    class UserToken
    {
        public function get($code){
    
        }
    }
    

    路由route.php

    //获取Token  为什么这里要用post 因为code安全性 get参数只能放在url路径下,因此用post将参数放到body里面去
    Route::post('api/:version/token/user','api/:version.Token/getToken');
    

    9.4 实现Token身份权限体系二
    现在我们要通过小程序向控制层Token接口的getToken方法请求,发送code.

    9.4.1写自定义的配置文件,在extra目录下的新建一个php file.名为wx
    wx.php

    return [
        //app_id app_secret为自己小程序申请时拥有的.
        'app_id' =>  '************',
        'app_secret' => '*****************',
        // %s 为占位符
        'login_url' => 'https://api.weixin.qq.com/sns/jscode2session?appid=%s&secret=%s&js_code=%s&grant_type=authorization_code',
    
    ];
    

    开始编写http请求,因为很多地方都要拥有http请求,因此将该方法写成公共方法,TP5提供了一个地方能够使TP5所有的类都使用,在application下的common.php

    // 应用公共文件
    /**
     * @param string $url get请求的地址
     * @param int $httpCode 返回状态码
     * @return mixed
     */
    function curl_get($url,&$httpCode = 0){
        $ch = curl_init();
        curl_setopt($ch,CURLOPT_URL,$url);
        curl_setopt($ch,CURLOPT_RETURNTRANSFER,1);
    
        //不做证书校验,部署在linux环境下请改为true
        curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,false);
        curl_setopt($ch,CURLOPT_CONNECTTIMEOUT,10);
        $file_contents = curl_exec($ch);
        $httpCode = curl_getinfo($ch,CURLINFO_HTTP_CODE);
        curl_close($ch);
        return $file_contents;
    }
    

    9.5 00:05:14


    11

    post请求 raw JSON

    如果通过code获取openid时候出现错误40029
    原因有可能 后台配置的appid 与 微信服务器工具配置的appid不是一个项目.

    我认为9.1----9.8之间的所有课程是非常重要了.
    讲解一登录权限,令牌的设计思想.是所有web开发都能用到的思想.
    在小程序调试api的时候,如果想debug调试只需要在小程序的index.js下url: baseUrl + '/token/user',更改成 url: baseUrl + '/token/user?XDEBUG_SESSION_START=????',

      getToken: function(){
        //调用登录接口
        wx.login({
          success: function(res){
            var code =res.code;
            console.log('code');
            console.log(code);
            wx.request({
              url: baseUrl + '/token/user',
              data:{
                code : code
              },
              method: 'POST',
              success:function(res){
                console.log(res.data);
                wx.setStorageSync('token', res.data.token);
              },
              fail:function(res){
                console.log(res.data);
              }
            })
          }
        })
      },
    

    然后会被自动进入PHPStrom下进行调试.当时小程序返回的空的token原因是在get方法下只调用了grantToken方法 但是没有接收grantToken返回的token.

    9.9商品详细接口分析与初步编写
    在9.1到9.8我们 实现了token 但是没有实现具体的应用
    上一节我们把 token的key value存在TP5的缓存中去了.默认缓存是存在runtime目录下的cache目录

    product表与product_img是一对多的关系.一个商品有多个详情,一个详情只属于一个商品.
    product表与product_property也是一对多的关系.

    测试发送请求的时候要看看是发送的get请求还是post请求.
    记住关联模型的时候要有 return

    原因有可能是请求get,但是实际请求的是post
    HttpException</abbr> in App.php line 369
    控制器不存在:V1

    9.10
    路由变量规则与分组
    TP5的路由是顺序匹配的
    例如
    这样就不会出错 位置没问题

    Route::get('api/:version/product/recent','api/:version.Product/getRecent');
    Route::get('api/:version/product/:id','api/:version.Product/getOne');
    Route::get('api/:version/product/by_category','api/:version.Product/getAllInCategory');
    

    这样就出错了 因为当你访问api/:version/product/recent时候匹配的是:id

    Route::get('api/:version/product/:id','api/:version.Product/getOne');
    Route::get('api/:version/product/recent','api/:version.Product/getRecent');
    Route::get('api/:version/product/by_category','api/:version.Product/getAllInCategory');
    

    解决方案 我们要对api/:version/product/:id中的id号有一个限定

    //商品详细 对id参数进行限定 当为整数的时候才会匹配这个路由, 第三个参数为可选参数
    Route::get('api/:version/product/:id','api/:version.Product/getOne',[],['id'=>'\d+']);
    

    路由分组
    好处
    1.让你少些几个url地址
    2.TP5路由匹配的效率要高

    //路由分组
    Route::group('api/:version/product',function (){
        Route::get('/:id','api/:version.Product/getOne',[],['id'=>'\d+']);
        Route::get('/recent','api/:version.Product/getRecent');
        Route::get('/by_category','api/:version.Product/getAllInCategory');
    });
    

    上面与下面代码等价

    //商品详细 对id参数进行限定 当为整数的时候才会匹配这个路由, 第三个参数为可选参数 规则是正则表达式
    Route::get('api/:version/product/:id','api/:version.Product/getOne',[],['id'=>'\d+']);
    Route::get('api/:version/product/recent','api/:version.Product/getRecent');
    //product分类详细
    Route::get('api/:version/product/by_category','api/:version.Product/getAllInCategory');
    
    

    9.11 闭包函数构建查询器
    peoduct_img表中order字段是序号 序号代表一张大图从上到下123456....
    一张竖长图分隔的

    在product.php 控制层中查询详细 关联了product_image表 要根据product_image的字段名升序排序

        public static function getProductDetail($id){
            $product = self::with([
                //Query
                'imgs' => function($query){
                    $query->with(['imgUrl'])
                    ->order('order','asc');
                }
            ])
                ->with(['properties'])
    //            ->with(['imgs.imgUrl'])
                ->find($id);
            return $product;
        }
    

    初看起来这种写法是比较麻烦的,但是你写多了这种方法是容易理解的.
    学习技巧
    有些东西不一定非要强制性现在搞明白 编写里面的小技巧内容写法很多.就像刚才我们写的,不要认为多么高深.有些时候我们不能明白某些写法,没关系.先学会怎么用它.比如下次遇见类似的这种情况.对关联模型下的模型根据字段进行排序.就可以套用这种写法.

    9.12 用户收货地址 -- 通过令牌获取用户标识
    现在需要编写一个全新的接口 因为之前都是查询的
    现在要编写一个 新增数据 的接口.
    保存用户信息的接口 需要权限,因为不能任何一个人都能保存到数据库信息.

    开始编写.首先先把基础的实现,然后再利用AOP的思想将权限加上去.


    image.png

    这样就能避免A用户修改B用户信息,A用户只能访问自己的用户信息.

    9.14 用户收货地址--模型新增和更新
    model下的User.php

    class User extends BaseModel
    {
        //如果在没有外键的一方调用一对一之间的关系 需要用hasOne  否则用belongsTo
        public function address(){
            return $this->hasOne('UserAddress','user_id','id');
        }
        public static function getByOpenId($openid){
            //我们的目的是通过openid找到相应的用户
            $user = self::where('openid','=',$openid)->find();
            return $user;
        }
    
    }
    

    9.14 有点不理解

    9.12到9.15还是需要多看看
    尤其是9.14 00:05:00这里开始

    返回的状态码不预期的时候,可以自定义状态码.

            //手动设置状态码
            return json(new SuccessMessage(),201);
    

    有点不懂得地方


    image.png
    image.png

    相关文章

      网友评论

          本文标题:1-2 8章前结束

          本文链接:https://www.haomeiwen.com/subject/ntkazxtx.html