关于JWT鉴权方案

作者: 时间: 2022-02-06 评论: 暂无评论

git:https://github.com/lcobucci/jwt

composer require lcobucci/jwt 3.4.6

jwt鉴权配置confi.php

  
'jwt_expire_time'        => 3600*24*10,                //token过期时间 默认10天
'jwt_secrect'            => '86L$1Q1@*##hgh!#@BG',    //签名秘钥
'jwt_iss'                => 'HDGHWDDAW@#8dj29009',    //发送端
'jwt_aud'                => '66dGzhw@dj@3#2ddaQ@',    //接收端
'jwt_refresh_expire_time'=> 3600*24*30,                //refresh_token过期时间 默认30天

Jwt.php 模块

 <?php 

namespace app\api\controller;
use Lcobucci\JWT\Builder;
use Lcobucci\JWT\Signer\Hmac\Sha256;
use Lcobucci\JWT\Parser;
use Lcobucci\JWT\ValidationData;

class Jwt{
    

private static $instance = null;

private $token;
private $decodeToken;
private $iss;  //发送数据端
private $aud;      //数据接收
private $uid; //用户UID
private $secrect;
private $expTime;


public static function getInstance(){
    if(is_null(self::$instance)){
        self::$instance = new self();
    }
    return self::$instance;
}

private function __construct(){
    
}

public function getToken(){
    return (string)$this->token;
}

public function setToken($token){
    $this->token = $token;
    return $this;
}

public function setUid($uid){
    $this->uid = $uid;
    return $this;
}    

public function getUid(){
    return $this->uid;
}

public function setExpTime($expTime){
    $this->expTime = $expTime;
    return $this;        
}    

public function setIss($iss){
    $this->iss = $iss;
    return $this;
}

public function setAud($aud){
    $this->aud = $aud;
    return $this;
}

public function setSecrect($secrect){
    $this->secrect =md5($this->uid.$secrect);
    return $this;
}

public function encode(){
    $time = time();
    $this->token = (new Builder())->setHeader('alg','HS256')
        ->setIssuer($this->iss)
        ->setAudience($this->aud)
        ->setIssuedAt($time)
        ->setExpiration($time+$this->expTime)
        ->set('uid',$this->uid)
        ->sign(new Sha256(),$this->secrect)
        ->getToken();
    
    return $this;
}


public function decode(){
    
    try{
        $this->decodeToken = (new Parser())->parse((string) $this->token); // Parses from a string
        $this->uid = $this->decodeToken->getClaim('uid');
        return $this->decodeToken;
    }catch (RuntimeException $e){
        throw new \Exception($e->getMessage());
    }
    
}
    
public function validate(){
    $data = new ValidationData(); // It will use the current time to validate (iat, nbf and exp)
    $data->setIssuer($this->iss);
    $data->setAudience($this->aud);
    $data->setId($this->uid);
    
    return $this->decode()->validate($data);
}


public function verify(){
    return $this->decode()->verify(new Sha256(),$this->secrect);
}

}

生成token

$jwt = Jwt::getInstance();
    $jwt->setIss(config('my.jwt_iss'))
           ->setAud(config('my.jwt_aud'))
            ->setSecrect(config('my.jwt_secrect'))
            ->setExpTime(config('my.jwt_expire_time'))
            ->setUid($uid);
    $token = $jwt->encode()->getToken();
      

中间件鉴权

<?php
namespace app\api\middleware;
use app\api\controller\Jwt;
class JwtAuth
{
    public function handle($request, \Closure $next)
    {
        $token = $request->header('Authorization');
        if (!$token) {
            return json(['status' => config('my.jwtExpireCode'), 'msg' => '请重新登录']);
        }
        if (count(explode('.', $token)) <> 3) {
            return json(['status' => config('my.jwtExpireCode'), 'msg' => '请重新登录']);
        }
        $jwt = Jwt::getInstance();
        $uid = $jwt->decode()->getClaim('uid');
        $jwt->setIss(config('my.jwt_iss'))
            ->setAud(config('my.jwt_aud'))
            ->setUid($uid)
            ->setSecrect(config('my.jwt_secrect'))
            ->setToken($token);

        if ($jwt->decode()->getClaim('exp') < time()) {
            return json(['status' => config('my.jwtExpireCode'), 'msg' => '请重新登录']);
        }
        if ($jwt->validate() && $jwt->verify()) {
            $request->uid = $uid;
            return $next($request);
        } else {
            return json(['status' => config('my.jwtExpireCode'), 'msg' => '请重新登录']);
        }

    }
}

状态机设计(任务,订单)

作者: 时间: 2022-02-06 评论: 暂无评论

1.为什么要有状态机?状态机又是什么?
有些订单的状态,任务的状态过于复杂,状态机是为了方便我们管理整个任务,订单的状态,防止错误的状态切换。毕竟现在都是团队合作。有一个模型来管理,也好规范其它程序员代码质量。

2.订单状态机

namespace app\api\service;

class OrderService
{
    //订单状态可以考虑成int 类型,mysql检索速度快
    public static $STATUS_NEW = 'new';   //新订单
    public static $STATUS_PAYED = 'payed'; //已支付
    public static $STATUS_DELIVERY = 'delivery'; //已发货
    public static $STATUS_RECEIVED = 'received'; //收货
    public static $STATUS_COMPLETE = 'complete';  //已完成

    private static $ALLOW_CHANGE_STATUS = [
        'new' => ['payed'],
        'payed' => ['delivery'],
        'received' => ['received'],
        'delivery' => ['complete'],
    ];

    /**
     * 状态切换
     * @param $status
     * @param $data
     * @throws \Exception
     */
    public function changeStu($status, $data)
    {
        //check order status
        $order=Order::find($data['orderNo']);
        if(!in_array($status,self::$ALLOW_CHANGE_STATUS[$order['status']])){
            throw new \Exception(' order status error');
        }
        
        
    }

    /**
     *  订单管理
     * @param $status
     * @param $data
     * @return bool|void
     */
    public function dispatch($status, $data)
    {
        $result = false;
        switch ($status) {
            case self::$STATUS_NEW:
                $result = self::createNew($data);
                break;
            case self::$STATUS_PAYED:
                $result = self::payed($data);
                break;
            case self::$STATUS_DELIVERY:
                $result = self::delivery($data);
                break;
            case self::$STATUS_RECEIVED:
                $result = self::received($data);
                break;
            case self::$STATUS_COMPLETE:
                $result = self::complete($data);
                break;
            default:
                $result = false;
        }
        return $result;
    }


    //各自功能实现
    private static function createNew($data)
    {
        //create new order
    }

    private static function payed($data)
    {
        //make the order payed
    }

    private static function delivery($data)
    {
        //make the order delivery
    }

    private static function received($data)
    {
        //make the order reveived
    }

    private static function complete($data)
    {
        //make the order complete
    }


}

php输出js文件

作者: 时间: 2021-06-25 评论: 暂无评论
header('content-type:application/octet-stream');
header('content-disposition:attachment; filename='.time().'.js');
echo $jsdata;

Linux 学习笔记 #4 磁盘管理

作者: 时间: 2019-08-23 评论: 暂无评论

1 df
选项与参数:

-a :列出所有的文件系统,包括系统特有的 /proc 等文件系统;
-k :以 KBytes 的容量显示各文件系统;
-m :以 MBytes 的容量显示各文件系统;
-h :以人们较易阅读的 GBytes, MBytes, KBytes 等格式自行显示;
-H :以 M=1000K 取代 M=1024K 的进位方式;
-T :显示文件系统类型, 连同该 partition 的 filesystem 名称 (例如 ext3) 也列出;
-i :不用硬盘容量,而以 inode 的数量来显示

文件系统                类型      容量  已用  可用 已用% 挂载点
/dev/mapper/centos-root xfs        17G  1.1G   16G    6% /
devtmpfs                devtmpfs  898M     0  898M    0% /dev
tmpfs                   tmpfs     910M     0  910M    0% /dev/shm
tmpfs                   tmpfs     910M  9.6M  901M    2% /run
tmpfs                   tmpfs     910M     0  910M    0% /sys/fs/cgroup
/dev/sda1               xfs      1014M  146M  869M   15% /boot
tmpfs                   tmpfs     182M     0  182M    0% /run/user/0
tmpfs                   tmpfs     182M     0  182M    0% /run/user/10

2 du
Linux du命令也是查看使用空间的,但是与df命令不同的是Linux du命令是对文件和目录磁盘使用的空间的查看,还是和df命令有一些区别的,这里介绍Linux du命令。

语法:

du [-ahskm] 文件或目录名称
选项与参数:

-a :列出所有的文件与目录容量,因为默认仅统计目录底下的文件量而已。
-h :以人们较易读的容量格式 (G/M) 显示;
-s :列出总量而已,而不列出每个各别的目录占用容量;
-S :不包括子目录下的总计,与 -s 有点差别。
-k :以 KBytes 列出容量显示;
-m :以 MBytes 列出容量显示;

[root@localhost ~]# du -ah
4.0K    ./.bash_logout
4.0K    ./.bash_profile
4.0K    ./.bashrc
4.0K    ./.cshrc
4.0K    ./.tcshrc
4.0K    ./anaconda-ks.cfg
4.0K    ./.bash_history
4.0K    ./test.txt
32K    .

3.fdisk Linux 的磁盘分区表操作工具
fdisk [-l] 装置名称

[root@localhost ~]# fdisk -l

磁盘 /dev/sda:21.5 GB, 21474836480 字节,41943040 个扇区
Units = 扇区 of 1 * 512 = 512 bytes
扇区大小(逻辑/物理):512 字节 / 512 字节
I/O 大小(最小/最佳):512 字节 / 512 字节
磁盘标签类型:dos
磁盘标识符:0x000ba19e

   设备 Boot      Start         End      Blocks   Id  System
/dev/sda1   *        2048     2099199     1048576   83  Linux
/dev/sda2         2099200    41943039    19921920   8e  Linux LVM

磁盘 /dev/mapper/centos-root:18.2 GB, 18249416704 字节,35643392 个扇区
Units = 扇区 of 1 * 512 = 512 bytes
扇区大小(逻辑/物理):512 字节 / 512 字节
I/O 大小(最小/最佳):512 字节 / 512 字节


磁盘 /dev/mapper/centos-swap:2147 MB, 2147483648 字节,4194304 个扇区
Units = 扇区 of 1 * 512 = 512 bytes
扇区大小(逻辑/物理):512 字节 / 512 字节
I/O 大小(最小/最佳):512 字节 / 512 字节

从中我们可以看出,有4个设备,分别为/dev/sda、/dev/sdb、/dev/mapper/cl-root、/dev/mapper/cl-swap。其中/dev/sda硬盘已经有2个分区分区为:/dev/sda1和/dev/sda2。/dev/mapper/cl-root和/dev/mapper/cl-swap两个设备是/dev/sda2分区创建的逻辑卷。这里的/dev/sdb硬盘设备并没有被分区

命令(输入 m 获取帮助):   

a toggle a bootable flag
b edit bsd disklabel
c toggle the dos compatibility flag
d delete a partition <==删除一个partition
l list known partition types
m print this menu
n add a new partition <==新增一个partition
o create a new empty DOS partition table
p print the partition table <==在屏幕上显示分割表
q quit without saving changes <==不储存离开fdisk程序
s create a new empty Sun disklabel
t change a partition's system id
u change display/entry units
v verify the partition table
w write table to disk and exit <==将刚刚的动作写入分割表
x extra functionality (experts only)

w保存,q离开

Linux 学习笔记 #2 文件权限

作者: 时间: 2019-08-23 评论: 暂无评论

1.Linux 文件基本属性
Linux系统是一种典型的多用户系统,不同的用户处于不同的地位,拥有不同的权限。
Linux中我们可以使用 ll 或者 ls –l

[root@localhost /]# ll
总用量 16
lrwxrwxrwx.   1 root root    7 8月  21 02:17 bin -> usr/bin
dr-xr-xr-x.   5 root root 4096 8月  21 02:38 boot
drwxr-xr-x.   2 root root    6 4月  11 2018 home

在Linux中第一个字符代表这个文件是目录、文件或链接文件等等。

当为[ d ]则是目录
当为[ - ]则是文件;
若是[ l ]则表示为链接文档(link file);
若是[ b ]则表示为装置文件里面的可供储存的接口设备(可随机存取装置);
若是[ c ]则表示为装置文件里面的串行端口设备,例如键盘、鼠标(一次性读取装置)。
接下来的字符中,以三个为一组,且均为『rwx』 的三个参数的组合。其中,[ r ]代表可读(read)、[ w ]代表可写(write)、[ x ]代表可执行(execute)。 要注意的是,这三个权限的位置不会改变,如果没有权限,就会出现减号[ - ]而已。

每个文件的属性由左边第一部分的10个字符来确定。类型+主+组+其它(如下图)。
363003_1227493859FdXT.png

2.Linux文件属主和属组
对于文件来说,它都有一个特定的所有者,也就是对该文件具有所有权的用户。
同时,在Linux系统中,用户是按组分类的,一个用户属于一个或多个组。
文件所有者以外的用户又可以分为文件所有者的同组用户和其他用户。

3.更改文件属性
① 变更文件或目录的所属群组 chgrp [-R] 所属组 文件名(目录名)

[root@localhost ~]# ll
-rw-r--r--. 1 root root    0 8月  23 19:19 test.txt
[root@localhost ~]# groupadd test
[root@localhost ~]# chgrp test test.txt
[root@localhost ~]# ll
-rw-r--r--. 1 root test    0 8月  23 19:19 test.txt

② chown:更改文件属主,也可以同时更改文件属组

chown [–R] 属主名 文件名
chown [-R] 属主名:属组名 文件名

[root@localhost ~]# chown root:root test.txt
[root@localhost ~]# ll
-rw-r--r--. 1 root root    0 8月  23 19:19 test.txt

③ chmod:更改权限
chmod [-R] xyz 文件或目录
xyz 是3位数数字,分别代表 属主 属组 其它 权限
比如:

属主是 rwx => 二进制 111=>十进制 4+2+1=7 => x=7
属组是 r-x => 二进制 100=>十进制 4+0+1=5 => y=5
其它是 r-x->  二进制 001=>十进制 4+0+1=1 => z=>5 

得到权限应该是 755

  root@localhost ~]# chmod 755 test.txt
  [root@localhost ~]# ll
  -rwxr-xr-x. 1 root test    0 8月  23 19:19 test.txt

还有一种写法:
chmod u|g|o|a[r|w|x] 文件
u|g|o|a (1)user (2)group (3)others(4)all 所有人 4种身份
+|-|= 增加 减去 设定
r|w|x 读,写,执行

[root@localhost ~]# ll
-rwxr-xr-x. 1 root test    0 8月  23 19:19 test.txt

[root@localhost ~]# chmod a=w test.txt
[root@localhost ~]# ll
--w--w--w-. 1 root test    0 8月  23 19:19 test.txt

[root@localhost ~]# chmod u=rwx,g=rx,o=x test.txt
[root@localhost ~]# ll
-rwxr-x--x. 1 root test    0 8月  23 19:19 test.txt