利用php-cli和任务计划实现刷新token功能的方法


Posted in PHP onMay 03, 2017

1、业务需求

需要实现这样一个功能:在第三方授权的认证当中,在用户首次登录授权我们会得到一个access_token,有效期为25小时,还会得到一个refresh_token,有效期为30天。

我们只要保存好这个refresh_token,在30天内我们都可以用这个refresh_token去请求一个api,他会返回一个新的access_token。这样我们只需要让用户授权一次,我们就可以获得长达30天的一个授权期限。

这里可以分为几个点:

<1>这个应该是要定期执行的一个任务。

25小时才会过期,那么我们12小时刷一次就足够了,并不需要很频繁的刷新。假设这样一种情况:让一个页面持续的运行,用一个while的死循环去执行一个任务,执行完之后sleep很长一段时间,然后再继续执行。这样做也是可以的,但是比较占资源。他执行的时间很少,等待的时间却很长,没必要这样一直等待。

<2>这个应该不需要是一个可以访问到的页面。

是我们内部执行的一个任务,不需要是人人可以访问到的一个页面。

<3>这个页面应该也要和框架融合在一起,可以访问到各种资源。

一个普通的php页面恐怕是不行的,我们需要跟框架融合的一个页面,需要可以访问到各种资源,比如说redis,比如说config,等等。

2、用cli模式运行codeigniter的页面

<1>cli的页面特性

什么是cli模式?就是命令行模式。我们可以不用url来访问php页面,而使用命令行来访问,这是可以的。

对页面来说,什么都不需要改变,比如:

>同样要是一个普通的controller,要继承自CI_Controller;

>要定义路由器,这个页面必须也是经由路由访问得到;

>甚至仍然可以添加这样的声明

defined('BASEPATH') OR exit('No direct script access allowed');

>可以通过添加一个判断让页面只能让cli访问:

public function __construct()
  {
    parent::__construct();
    if (!is_cli())
      exit("不正确的访问方式");
  }

>通过echo打印在命令行上面,就如打印在页面上一样

<2>怎么通过命令行访问

cd E:\xxx\xxx\phpSite  //网站的根目录,即index.php所在目录

php index.php aaa bbb ccc  //即访问网址为yourdomain.com/index.php/aaa/bbb/ccc这样的地址注意:

>第一行是转到网站根目录这个路径;

>第二行php是调用了php.exe这个是因为我们有设置php的环境变量;

>index.php不可以缺少,因为这里我们没有走服务器了,没有经过服务器的url-rewrite,所以这个index.php是必不可少的。

我们可以将这两行代码放在一个文本文件里面,将名字改为refresh.bat,双击这个bat文件,他就会执行一次,相当于打开命令行来执行

如果我们需要调试的话,不要让弹出的命令行自动关掉,我们可以在加上第三行代码,加一个单词就可以了:pause

他就会停住并且显示相关的信息方便我们调试。

<3>页面调试

如下例子,此页面通过把一个值每刷新页面一次累加一次,存在redis里,来验证页面是否有被访问过:

<?php
defined('BASEPATH') OR exit('No direct script access allowed');
/**
 * Created by PhpStorm.
 * Date: 2017/2/20
 * Time: 23:18
 */
class Refresh_token extends CI_Controller
{
  public function __construct()
  {
    parent::__construct();
    if (!is_cli())
      exit("不正确的访问方式");
  }
  public function index()
  {
    $oldData = $this->redis_model->get_access_token('1234');
    if ($oldData == null)
      $oldData = 0;
    $newData = $oldData + 1;
    $this->redis_model->set_access_token('1234',$newData);
    echo 'its refresh_token page!';
  }
}

3、创建计划任务让他运行bat文件

利用php-cli和任务计划实现刷新token功能的方法

利用php-cli和任务计划实现刷新token功能的方法

利用php-cli和任务计划实现刷新token功能的方法

利用php-cli和任务计划实现刷新token功能的方法

4、刷新token

<1>命名的规则

刷新token首先想到的是遍历redis。redis那么多应该怎么遍历?我想到的是给不同类型redis设定不同的前缀。

比如说,所有用户的refresh_token的key都这样写:"refresh_token_用户id"。然后用redis的模式匹配就可以把以"refresh_token_"开头的key找出来,然后一条条处理。

<2>redis遍历

首先,redis是有模式识别的功能,参见手册:https://redis.io/commands/keys

其次,php原生的redis组件是有这个模式识别的功能。原生的用法大概是这样:

// 原生redis类库,不需要config/redis.php 
$redis = new Redis(); 
$redis->connect('127.0.0.1',6379); 
//$redis->set('key10','xx10',20);//第三个参数是存续时间,单位是秒,如果不填则为永久 
echo $redis->get('key10');

大致说一下,ci框架的redis操作api呢是在php原生的api上面进行了一层封装,而他这个封装呢不包括这个模式识别。

本人的自定义操作api是从框架api直接拷贝过来的,也是为了方便添加更多方法。在原生的框架上面添加总归不太好,比如说将来要升级、移植等问题。写成自己的类库想怎么改怎么改。

下面是添加这个模式识别api:

public function keys($pattern)
  {
    return $this->_redis->keys($pattern);
  }

然后在model里面这样调用:

public function get_keys($pattern)
  {
    return $this->rediscli->default->keys($pattern);
  }

然后在controller里面使用:

//    $this->redis_model->set_redis('hello'.'1','my_hello_1',12345);
//    $this->redis_model->set_redis('hello'.'2','my_hello_2',12345);
//    $this->redis_model->set_redis('hello'.'3','my_hello_3',12345);

    $vals = $this->redis_model->get_keys('hello'.'*');
    if ($vals != null)//注意这里,他是一个array,如果返回的是匹配到0个,那么不会是一个空的有效的0长度的array,而确实是一个null。
    {
      foreach ($vals as $val)
      {
        echo '</br>';
        echo $val;
      }
    }

这样就可以完成对特定前缀的遍历了!

注意:这里要特别说明一下,我们在写入这个token的时候,会将有效期写进去,那么只要这个有效期的值是正确的,我们取到这个token必定是有效的,那么我们拿这个有效的token去刷新,必然是成功的。一般不存在刷新失败的情况。因为这个token一旦失效我们也就取不到了。

以上这篇利用php-cli和任务计划实现刷新token功能的方法就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持三水点靠木。

PHP 相关文章推荐
不用GD库生成当前时间的PNG格式图象的程序
Oct 09 PHP
PHP字符编码问题之GB2312 VS UTF-8解决方法
Jun 23 PHP
PHP中curl_setopt函数用法实例分析
Apr 16 PHP
PHP实现GIF图片验证码
Nov 04 PHP
php实现图片缩略图的方法
Mar 29 PHP
详解PHP处理字符串类似indexof的方法函数
Jun 11 PHP
php支付宝APP支付功能
Jul 29 PHP
PHP扩展Swoole实现实时异步任务队列示例
Apr 13 PHP
TP5.0框架实现无限极回复功能的方法分析
May 04 PHP
tp5.1 框架路由操作-URL生成实例分析
May 26 PHP
PHP正则表达式函数preg_replace用法实例分析
Jun 04 PHP
PHP实现简单的计算器
Aug 28 PHP
利用php-cli和任务计划实现订单同步功能的方法
May 03 #PHP
php删除数组指定元素实现代码
May 03 #PHP
在php7中MongoDB实现模糊查询的方法详解
May 03 #PHP
PHP里面把16进制的图片数据显示在html的img标签上(实现方法)
May 02 #PHP
php 使用curl模拟ip和来源进行访问的实现方法
May 02 #PHP
ThinkPHP实现静态缓存和动态缓存示例代码
May 02 #PHP
php 函数使用可变数量的参数方法
May 02 #PHP
You might like
PHP压缩html网页代码(清除空格,换行符,制表符,注释标记)
2012/04/02 PHP
YII模块实现绑定二级域名的方法
2014/07/09 PHP
CI框架Session.php源码分析
2014/11/03 PHP
php检查字符串中是否有外链的方法
2015/07/29 PHP
在Laravel 的 Blade 模版中实现定义变量
2019/10/14 PHP
Ext.get() 和 Ext.query()组合使用实现最灵活的取元素方式
2011/09/26 Javascript
JSON为什么那样红为什么要用json(另有洞天)
2012/12/26 Javascript
用js写了一个类似php的print_r输出换行功能
2013/02/18 Javascript
javascript从定义到执行 你不知道的那些事
2016/01/04 Javascript
使用MUI框架模拟手机端的下拉刷新和上拉加载功能
2017/09/04 Javascript
基于vue v-for 循环复选框-默认勾选第一个的实现方法
2018/03/03 Javascript
Angular刷新当前页面的实现方法
2018/11/21 Javascript
js的对象与函数详解
2019/01/21 Javascript
VUEX 数据持久化,刷新后重新获取的例子
2019/11/12 Javascript
python批量下载图片的三种方法
2013/04/22 Python
TensorFlow模型保存和提取的方法
2018/03/08 Python
python3 实现一行输入,空格隔开的示例
2018/11/14 Python
python文件拆分与重组实例
2018/12/10 Python
python爬虫简单的添加代理进行访问的实现代码
2019/04/04 Python
使用selenium模拟登录解决滑块验证问题的实现
2019/05/10 Python
python 叠加等边三角形的绘制的实现
2019/08/14 Python
树莓派4B+opencv4+python 打开摄像头的实现方法
2019/10/18 Python
python多线程案例之多任务copy文件完整实例
2019/10/29 Python
使用PyCharm官方中文语言包汉化PyCharm
2020/11/18 Python
浅谈盘点5种基于Python生成的个性化语音方法
2021/02/05 Python
CSS3 简写animation
2012/05/10 HTML / CSS
美国一家主营日韩美妆护肤品的在线商店:iMomoko
2016/09/11 全球购物
一套SQL笔试题
2016/08/14 面试题
Java中的基本数据类型所占存储空间大小固定的吗
2012/02/15 面试题
企业标语口号
2014/06/10 职场文书
领导干部对照检查材料
2014/08/24 职场文书
房产遗嘱范本
2015/08/06 职场文书
2016年七夕情人节宣传语
2015/11/25 职场文书
Pytorch 如何实现常用正则化
2021/05/27 Python
Redis 持久化 RDB 与 AOF的执行过程
2021/11/07 Redis
SpringBoot使用ip2region获取地理位置信息的方法
2022/06/21 Java/Android