php jwt代替session 无状态登录

因为我是在tp框架中运行的

首页下载tp框架 此版本为5.1版本

composer create-project topthink/think tp55

然后 下载 jwt php封装库

cd tp55

composer require firebase/php-jwt


然后在lib目录下新建Jwt.php 类

内容为

<?php
/**
 * Created by PhpStorm.
 * User: Administrator
 * Date: 2019/5/30
 * Time: 9:09
 */

namespace app\lib;

class Jwt
{
    public static function setJwt($data)
    {
        $key = md5("123456");
        $time = time(); //当前时间
        $token = [
            'iss' => 'https://www.huxierong.xyz', //签发者 可选
            'aud' => 'https://www.huxierong.xyz', //接收该JWT的一方,可选
            'iat' => $time, //签发时间
            'nbf' => $time, //(Not Before):某个时间点后才能访问,比如设置time+30,表示当前时间30秒后才能使用
            'exp' => $time + 432000, //过期时间,这里设置5天
            'data' => $data
        ];
        return \Firebase\JWT\JWT::encode($token, $key);
    }

    public static function getJwt($jwt)
    {
        try {
            $key = md5("123456");
            $res = \Firebase\JWT\JWT::decode($jwt, $key, ['HS256']);
            $arr = json_decode(json_encode($res), true);//转为数组
            return $arr;
        } catch (\Firebase\JWT\SignatureInvalidException $e) {  //签名不正确
            echo 'token签名校验不通过!';
        } catch (\Firebase\JWT\BeforeValidException $e) {  // 签名在某个时间点之后才能用
            echo 'token暂时未启用!';
        } catch (\Firebase\JWT\ExpiredException $e) {  // token过期
            echo 'token已过期!';
        } catch (\UnexpectedValueException $e)
        {
            echo "token非法!";
        }catch (\Exception $e)
        {
            echo "其他错误!";
        }
    }
}

在Index.php 控制器中新建两个方法

<?php
namespace app\index\controller;

use app\lib\Jwt;
use think\facade\Request;

class Index
{
    public function createJwt()
    {
        echo Jwt::setJwt(['user_id'=>1]);
    }

    public function getJwt()
    {
        $auth = Request::header('auth');
        dump(Jwt::getJwt($auth));
    }
}

在route.php里 添加2个路由

<?php
use \think\facade\Route;
Route::get("createJwt","index/Index/createJwt"); //创建jwt
Route::get("getJwt","index/Index/getJwt"); //获取jwt

在tp55这个根目录下运行

php think run -H 0.0.0.0 –port 3333

首先运行 createJwt

http://127.0.0.1:3333/createJwt

如果没有意外的话 就会打印出一串base64代码

eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJodHRwczpcL1wvd3d3Lmh1eGllcm9uZy54eXoiLCJhdWQiOiJodHRwczpcL1wvd3d3Lmh1eGllcm9uZy54eXoiLCJpYXQiOjE1NTkxNzkxNDYsIm5iZiI6MTU1OTE3OTE0NiwiZXhwIjoxNTU5NjExMTQ2LCJkYXRhIjp7InVzZXJfaWQiOjF9fQ.4MvOLasxrM-S7FghmYxvw_sl6Xu78b2xaaSnLFMjl4w

然后使用 postman 把这一串base64 扔进header auth里面

运行

就显示刚才加密的数据啦。

typescript简单实现ajax请求

我们首先定义一个接口

interface UtilConfig{
  url:string;
  method:string;
  data:string;
  dataType:string;
  success:(str:JSON | string)=>void;
  error?:(str:string)=>void;
}

接着我们编写一个函数我就把它取名为ajax

function ajax(config:UtilConfig):void{
  let xhr = new XMLHttpRequest()
  xhr.open(config.method,config.url,true)
  xhr.send(config.data)
  xhr.onreadystatechange = function()
  {
    if(xhr.readyState==4){
      if(xhr.status==200)
      {
        if(config.dataType.toLowerCase()=="json")
        {
          config.success(JSON.parse(xhr.responseText))
        }else{
          config.success(xhr.responseText)
        }
      }else{
        if(config.error)
        {
          config.error(xhr.responseText)
        }
      }
    }
  }
}

这个函数的参数用来指定接口 里面就是实现XmlHttpRequest类来发送请求

接着我们允许一下这个函数

ajax({
  url:"http://localhost:5666/api/v1/getId/1",
  method:"get",
  data:'id=1',
  dataType:"json",
  success:(res:string | JSON)=>
  {
    console.log(res)
  },
  error:(res:string)=>{
    console.log(res)
  }
})

查看结果

ok成功

手机版b站 使用puppeteer爬取分类,和分类下最新的视频信息

目录结构

data 爬取操作
config 一些配置项
database 爬取数据库
handle 处理爬取到的数据写进数据库中

index.js 文件

里的runPa 方法是处理 数组里要处理的爬取文件(data)

runPa方法里通过 child.on(“message” ) 来做进程间的通讯

data 目录下的 js文件 通过 process.send({result}) 方法与index.js通讯

handle 里的js文件

通过 传进来的 res 来入库处理。

git地址 https://gitee.com/huxierong/bilbil_pachongg

mysql8.0 主从同步

新建my3330.cnf

新建my.cnf

my.cnf

log-bin=mysql-bin
server-id=1
port=3320

my3330.cnf

server-id=2
port=3330
relay_log = mysql-relay-bin

进入3320这个端口

添加 一个用户repl

CREATE USER ‘repl’@’127.0.0.1’ IDENTIFIED WITH mysql_native_password BY ‘123456’;

GRANT REPLICATION SLAVE ON . TO ‘repl’@’127.0.0.1’;

运行show master status;

进入3330端口

mysql> CHANGE MASTER TO
MASTER_HOST='127.0.0.1',
MASTER_PROT=3320,
MASTER_USER='repl',
MASTER_PASSWORD='123456',
MASTER_LOG_FILE='mysql-bin.000005',
MASTER_LOG_POS=155;

运行start slave

查看show slave status\G;

这两个为yes就代表成功了。

测试一下

在3320里 create database testSlave;

在3330里运行 show databases;

ok,大功告成。

简单构建工具parcel 轻松构建vue

首先

npm init

然后下载 vue parcel

npm install vue

npm install parcel-bundler

目录结构

App.vue

<template>
    <div>
        app
        <img src="./d.jpg" alt="">
    </div>
</template>

<script>
export default {
  data() {
    return {};
  }
};
</script>

<style lang="stylus" scoped>
div
    font-size 30px
</style>

main.js

import Vue from 'vue'
import App from './App.vue'

new Vue({
  el: '#app',
  render: h => h(App)
})

index.html

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
</head>
<body>
  <div id="app"></div>
  <script src="./src/main.js"></script>
</body>
</html>

下载css预处理器 stylus

npm install stylus stylus-loader -D

运行 parcel index.html

parcel文档 https://parceljs.org/getting_started.html

vue-cli 3 手机版b站 个人中心页

先看图

我把这个页面拆分了5个组件

其中最重要的是 跳转到设置页的动画效果

<transition name="slide-fade">
     <person-setting v-if="showSetting"></person-setting>
</transition>
.slide-fade-enter-active {       transition: all .3s ease;     }     .slide-fade-leave-active {       transition: all .3s ease;     }     .slide-fade-enter, .slide-fade-leave-to     {       transform:  
translateX(100%); opacity: 0; }

还有 浏览器返回键触发

if (window.history && window.history.pushState) {
       history.pushState(null, null, document.URL)
       window.addEventListener('popstate', this.goBack, false)
}
goBack()
{
   setTimeout(()=>{
      this.set_position = "position:relative;top:0px"
   },500)
				
   window.removeEventListener('popstate', this.goBack, false)
   this.showSetting = false
},

详细请看代码

git@gitee.com:huxierong/bilbil.git

thinkphp5.1 微信支付实现 jsapi支付 和app支付

我们先下载 微信的sdk 改一下后目录

我定义了一个 抽象类 payment.php 为了以后接入其他支付

最主要的是WxPay.PHP

<?php
/**
 * Created by PhpStorm.
 * User: Administrator
 * Date: 2019/5/13
 * Time: 9:23
 */
namespace payment\weixin\pay;
use payment\payment;
use payment\weixin\lib\WxPayApi;
use payment\weixin\lib\WxPayNotify;
use payment\weixin\lib\WxPayUnifiedOrder;
use think\Exception;
class WxPay extends payment
{
    /**
     * 支付
     * @param $arr
     * @return array|mixed
     */
    public static function pay($arr)
    {
        try{
            $config = new WxConfig();
            //②、统一下单
            $input = new WxPayUnifiedOrder();
            //判断是公众号 还是 app
            if($arr['trade_type']=="JSAPI")
            {
                $tools = new JsApiPay();
                $openId = $tools->GetOpenid();
                $input->SetOpenid($openId);
            }
            $input->SetBody($arr['body']); //设置商品或支付单简要描述
            //订单自定义参数,回调携带返回
            if(array_key_exists('attach',$arr))
            {
                $input->SetAttach($arr['attach']);
            }
            //自定义 商户订单号
            $input->SetOut_trade_no($arr['trade_no']);
            //金额
            $input->SetTotal_fee($arr['total_fee']);
            $input->SetTime_start(date("YmdHis"));
            $input->SetTime_expire(date("YmdHis", time() + 600));
            $input->SetNotify_url($arr['notify_url']);
            $input->SetTrade_type($arr['trade_type']);
            $order = WxPayApi::unifiedOrder($config, $input);

            if($arr['trade_type']=="JSAPI")
            {
                $orders = $tools->GetJsApiParameters($order);
                return ['status'=>1,'message'=>'OK','data'=>$orders];
            }
            return ['status'=>1,'message'=>'OK','data'=>$order];

        }catch (\Exception $e)
        {
            return ['status'=>0,'message'=>$e->getMessage(),'data'=>''];
        }

    }

    public static function notify($arr)
    {
        $notify = new WxPayNotify();
        $config = new WxConfig();
	    $res = $notify->Handle($config);

        if($res)
        {
            $xml = $GLOBALS['HTTP_RAW_POST_DATA'];
            $data = json_decode(json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)), true);
            $status = 1;
            $msg = '<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>';
        }else
        {
            $data = [];
            $status = 0;
            $msg = '<xml><return_code><![CDATA[FAIL]]></return_code><return_msg><![CDATA[FAIL]]></return_msg></xml>';
        }
        return ['status'=>$status,'msg'=>$msg,'data'=>$data];
    }

}

Index.php引用

<?php
namespace app\admin\controller;

use payment\weixin\pay\WxPay;
use think\Controller;

class Index extends Controller
{
public function index()
{
/*
* app支付
*/
// $arr = [];
// $arr['attach'] = [];
// $arr['trade_type'] = "APP";
// $arr['body'] = "body";
// $arr['trade_no'] = date("YmdHis").substr(implode(NULL, array_map('ord', str_split(substr(uniqid(), 7, 13), 1))), 0, 8);
// $arr['total_fee'] = 1;
// $arr['notify_url'] = "https://xxxx/wxNotify";
// $res = WxPay::pay($arr);
// $res['data'] = json_encode($res['data']);
// return json($res);

/*
* js公众号
*/
// $arr = [];
// $arr['attach'] = [];
// $arr['trade_type'] = "JSAPI";
// $arr['body'] = "";
// $arr['trade_no'] = date("YmdHis").substr(implode(NULL, array_map('ord', str_split(substr(uniqid(), 7, 13), 1))), 0, 8);
// $arr['total_fee'] = 1;
// $arr['notify_url'] = "https://xxxx/wxNotify";
// $res = WxPay::pay($arr);

}

/*
* 回调
*/
public function wxNotify()
{
$res = WxPay::notify([]);
if($res['status']==1)
{
echo $res['msg'];
}else
{
echo $res['msg'];
}
exit();
}


}

全部代码

python selenium 谷歌浏览器后台运行

from selenium import webdriver
driver = webdriver.Chrome()
driver.get("http://www.baidu.com")
print(driver.title)

这段代码运行会调起浏览器


加上

option = webdriver.ChromeOptions()
option.add_argument('headless')

这个配置后

from selenium import webdriver
option = webdriver.ChromeOptions()
option.add_argument('headless')
driver = webdriver.Chrome(chrome_options=option)
driver.get("http://www.baidu.com")
print(driver.title)

控制台直接打印