利用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 相关文章推荐
用PHP控制用户的浏览器--ob*函数的使用说明
Mar 16 PHP
php 上一篇,下一篇文章实现代码与原理说明
May 09 PHP
php 数组排序 array_multisort与uasort的区别
Mar 24 PHP
探讨如何使用SimpleXML函数来加载和解析XML文档
Jun 07 PHP
PHP 抽象方法与抽象类abstract关键字介绍及应用
Oct 16 PHP
php array_udiff_assoc 计算两个数组的差集实例
Nov 12 PHP
PHP 序列化和反序列化函数实例详解
Jul 18 PHP
PHP中include和require的区别实例分析
May 07 PHP
php生成条形码的图片的实例详解
Sep 13 PHP
PHP实现基于栈的后缀表达式求值功能
Nov 10 PHP
laravel 实现根据字段不同值做不同查询
Oct 23 PHP
4种Windows系统下Laravel框架的开发环境安装及部署方法详解
Apr 06 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实现QQ空间获取当前用户的用户名并生成图片
2015/07/25 PHP
PHP实现登录验证码校验功能
2018/05/17 PHP
laravel 错误处理,接口错误返回json代码
2019/10/25 PHP
JavaScript实现自动对页面上敏感词进行屏蔽的方法
2015/07/27 Javascript
jQuery三级下拉列表导航菜单代码分享
2020/04/15 Javascript
解决js图片加载时出现404的问题
2020/11/30 Javascript
关于javascript中dataset的问题小结
2015/11/16 Javascript
jquery利用拖拽方式在图片上添加热链接
2015/11/24 Javascript
微信jssdk在iframe页面失效问题的解决措施
2016/03/03 Javascript
基于原生JS实现图片裁剪
2016/08/01 Javascript
jQuery子元素过滤选择器用法示例
2016/09/09 Javascript
js html css实现复选框全选与反选
2016/10/09 Javascript
Nodejs下DNS缓存问题浅析
2016/11/16 NodeJs
如何清除IE10+ input X 文本框的叉叉和密码输入框的眼睛图标
2016/12/21 Javascript
基于cookie实现zTree树刷新后展开状态不变
2017/02/28 Javascript
Angularjs 实现移动端在线测评效果(推荐)
2017/04/05 Javascript
jQuery实现简单的下拉菜单导航功能示例
2017/12/07 jQuery
对angular 监控数据模型变化的事件方法$watch详解
2018/10/09 Javascript
mpvue实现微信小程序快递单号查询代码
2020/04/03 Javascript
vue单文件组件无法获取$refs的问题
2020/06/24 Javascript
python3实现抓取网页资源的 N 种方法
2017/05/02 Python
浅述python中深浅拷贝原理
2018/09/18 Python
PyCharm设置护眼背景色的方法
2018/10/29 Python
利用python脚本如何简化jar操作命令
2019/02/24 Python
python中设置超时跳过,超时退出的方式
2019/12/13 Python
python计算二维矩形IOU实例
2020/01/18 Python
Python图像处理库PIL的ImageEnhance模块使用介绍
2020/02/26 Python
python计算Content-MD5并获取文件的Content-MD5值方式
2020/04/03 Python
用html5实现语音搜索框的方法
2014/03/18 HTML / CSS
HTML5的Video标签有部分MP4无法播放的问题解析(多图)
2017/08/18 HTML / CSS
HTML5 input新增type属性color颜色拾取器的实例代码
2018/08/27 HTML / CSS
就业自荐书
2013/12/05 职场文书
关于教师节的演讲稿
2014/09/04 职场文书
2014年医院十一国庆节活动方案
2014/09/15 职场文书
入党培养人考察意见
2015/06/08 职场文书
Golang全局变量加锁的问题解决
2021/05/08 Golang