美文网首页
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章前结束

    9.1 令牌.之前我们做的所有接口都没有权限控制,所有用户都可以调用.但是有些接口能公开访问.有些接口就不能公开访...

  • 写在结束前

    参加21天写作活动已19天,这是我第一次参加这样的活动。今日收到的写作主题是写一写我们参加此次活动的小伙伴。说实在...

  • 结束前的落寞

    明天就是就是给学生上最后一天的课了,心里有点空空的感觉,今天总感觉自己有点失落,也许是想家了,雷州的每天都是雨天,...

  • 双十一结束前…

  • 在结束前想你

    好像流星划过夜空 一切都变得那般的飘渺 我的心随着风儿在飞 飞到那个没有伤愁的边界 想说大地的声音 想看大地的心脏...

  • 在秋天结束前

    对啊。我从一个城市到另外一个城市,从陌生到慢慢熟悉,那蹩脚的粤语还是挺让人想发笑的。很多人都在问:你为什么要来深圳...

  • 写在实习结束前

    要动真格了 要回学校做课题,结束折腾人的10天实习。这半个月太屎了,这次回学校是要动真格,写两篇文章! 注意事项 ...

  • 写在2019结束前

    这一年可谓万分折腾,无论家人还是自己。老爸经历了肠糜烂,车祸,高血压,最后所幸都幸免于难;自己正式进入三十周岁,经...

  • 18岁结束前

    文//佳之如许❤ 2020年10月18日 星期六 天气阴 十八岁这年,我过的似乎和之前十几年没什么不同,但细细想来...

  • 写在2021结束前

    2021年就只剩几天了。是不是年龄越大,时间过起来就越快呢? 这一年,日子依旧平平淡淡,也有小小的波澜,生活没有大...

网友评论

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

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