什么是access数据库程序设计-access程序
正儿八经目录

吐槽
之所以写这篇文章是因为之前的开发没有使用微信小程序给的session作为token认证。 这次打算使用多端同步的uniapp来开发小程序,方便后期多端传输,所以想尝试一下新的东西。 另外在热榜上看到一篇文章说“使用access_token作为token请求验证接口,使用checkSession检测access_token是否过期”。 不得不感叹,现在的技术呃这么差吗? 这简直就是一个错误! !
下面说说为什么不能用access_token作为token
所以,access_token只是用来调用微信提供的一些api服务,access_token只有两个小时。 是否使用access_token作为小程序的token?不仅不满足暴露的问题,而且还有时间限制
下面说说checkSession是用来检测什么的?
所以! checkSession用于检测session_key而不是access_token,access_token是根据小程序的appid和secret确定的,没有单一的用户代表

什么是代币?
顾名思义,token就是令牌,是一种身份标记。 它用于确定与服务器的身份。 具有时效性,身份标识在有效时间后失效。

设计思路(点击方法跳转原文)
通过小程序客户端发起的**wx.login()**获取临时登录凭证码,回传给开发者服务器,通过提供的auth.code2Session接口换取用户唯一标识openid和session key session_key通过微信。 并以session_key为name,openid为value,将数据存储到redis中,这里我设置时间为48h
如果服务器令牌无效,则客户端的登录状态也将无效。 失效后,重新登录什么是access数据库程序设计,执行以上步骤; 如果客户端checkSession失效或者本地数据缓存失效,也会重新登录
以上两步保证了小程序端的token都是最新的。 缺点是存储在服务器上的数据不能及时失效,只能等待redis过期。
上述设计逻辑满足下图:

代码操纵操作
以Thinkphp5.0.24为例
在 public 文件夹中创建一个 php 文件 access_token.php
用于接收前端wx.login方法获取的code并换回openid和session_key,并以session_key为name,openid为value将数据存入redis。 这里我把时间设置为48h
<?php
//小程序登录
$appid="";//小程序id
$secret="";//密钥
$code=$_GET['code'];
curl_get("https://api.weixin.qq.com/sns/jscode2session?appid=$appid&secret=$secret&js_code=$code&grant_type=authorization_code");
function curl_get($url){
 
   $header = array(
       'Accept: application/json',
    );
    $curl = curl_init();
    //设置抓取的url
    curl_setopt($curl, CURLOPT_URL, $url);
    //设置头文件的信息作为数据流输出
    curl_setopt($curl, CURLOPT_HEADER, 0);
    // 超时设置,以秒为单位
    curl_setopt($curl, CURLOPT_TIMEOUT, 1);
 
    // 超时设置,以毫秒为单位
    // curl_setopt($curl, CURLOPT_TIMEOUT_MS, 500);
 
    // 设置请求头
    curl_setopt($curl, CURLOPT_HTTPHEADER, $header);
    //设置获取的信息以文件流的形式返回,而不是直接输出。
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
    curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);

    //执行命令
    $data = curl_exec($curl);
 
    // 显示错误信息
    if (curl_error($curl)) {
        print "Error: " . curl_error($curl);
    } else {
        // 打印返回的内容
        // print_r($data);
         
         $result=json_decode($data,true);
          // 开启redius
         ini_set('session.save_handler', 'redis');
         ini_set('session.save_path', 'tcp://127.0.0.1:6379');
         $redis = new redis();
         $redis->connect('127.0.0.1', 6379);
         //写入redius session_key名命的openid数据 默认存储48h
        curl_close($curl);
        $redis->set($result['session_key'],$result['openid'],24*60*60*2);
        die(
        json_encode(
            array(
            'code' => 200,
            'msg' => $result
        ),480)
);
       
          
    }
}
 ?>
在tp框架(application/index/controller)新建一个Api.php控制器
用于检测服务端token是否存在,以便小程序进行重新登录操作
<?php
namespace app\index\controller;
use think\Db;
use think\cache\driver\Redis;
use app\index\controller\Base;
class Api extends Base
{
    
    // 验证session_key是否过期(服务器默认48h,到期后自动删除,查询不到表示过期)
    public function check_session()
    { 
        $session_key=input('session_key');
        $redis = new Redis();
        //读取数据
        $result= $redis->get($session_key);

        if ($result) {
            // 存在记录
           die(
        json_encode(
            array(
            'code' => 200,
            'msg' => 'token验证通过'
        ),480)
);
        } else {
            // 已被处理或者不存在 请求重新登陆
            die(
        json_encode(
            array(
            'code' => 100,
            'msg' => 'token验证失败,请重新登录'
        ),480)
);
        }
        
    
       
    }
}
客户端包装器
/**
 * token.js,全局校验方法,可以自己补充
 */
export default {
	login: function(session) {  
		let that = this;
		uni.showLoading({
		  title: '登录中...'
		});
				
		uni.login({
		  provider: 'weixin',
		  success: loginRes => {
		    console.log(loginRes);
		    that.code = loginRes.code;
		    //  将用户登录code传递到后台置换用户SessionKey、OpenId等信息
			uni.request({
			    url: 'https://serverhost/wx_token.php', //仅为示例,并非真实接口地址。
			    data: {
			        code:loginRes.code
			    },
				method: 'GET',
			    header: {

			        'content-type': 'application/x-www-form-urlencoded' //自定义请求头信息
			    },
			    success: (res) => {
			        console.log(res.data);
			       console.log(res.data.msg.session_key)
				   uni.hideLoading()
				   //存取session
				   uni.setStorageSync('session', res.data.msg.session_key);
				   //openid只需要服务通过session请求redis即可
			    }
			});
		
		   
		  },
		  fail: () => {
		    uni.showToast({ title: '获取 code 失败', icon: 'none' });
		  }
		});
		
	},
        //检测token 每次发起业务请求检测即可
	check_token: function(session) {  
		let that=this;
		//微信检测
		uni.checkSession({
		  success () {
		    //session_key 未过期,并且在本生命周期一直有效
			 console.log("未过期")
			
			 //没有过期在判断下存储是否存在 后需提交业务需要用到
			 const session = uni.getStorageSync('session');
			 	if (session=='') {
					console.log("session不存在");
					that.login()
			 	}else{
					//检测服务器的
					console.log("session存在-校验合法性");
					//验证检测服务器session有效性
					uni.request({
					    url: 'https://serverhost/index.php/index/Api/check_session', //仅为示例,并非真实接口地址。
					    data: {
					        session_key:session
					    },
						method: 'POST',
					    header: {
					        'content-type': 'application/x-www-form-urlencoded' //自定义请求头信息
					    },
					    success: (res) => {
							if (res.data.code!=200)
							{	

								
								//服务器token已过期 重新登录
								console.log("服务器token已过期 重新登录");
								that.login()
								
							}else{
								console.log("服务器token有效");
							}
						 
					    }
					});
					
					
					
				}
				
			 
		  },
		  fail () {
		    // session_key 已经失效,需要重新执行登录流程
		   console.log("session过期")
		   
		   that.login()
		  }
		})
		
		
	
		
	}
}
import token from '@/sdk/token.js'
// 挂载到全局
Vue.prototype.$token = token
 this.$token.check_token()
演示
uniapp打包成微信小程序运行后
1.没有本地缓存,没有redis记录demo 2.没有本地缓存demo

3.服务器端没有redis记录演示
上面已经对所有的可能性做了实验,除了【更新新token后无法及时使最后一个token失效】的问题,我找不到其他问题
如何进行令牌认证
让我们看演示
验证token在服务端是否有效什么是access数据库程序设计,只需要查询token即可。 如果存在,则意味着成功。 直接把openid拿出来写业务逻辑代码。 如果失败,让小程序重新登录。 这些都可以根据返回码来完成。
<?php
// 访问路由 https://***/index.php/index/Api/index

namespace app\index\controller;
use think\Db;
use think\cache\driver\Redis;
use app\index\controller\Base;
class Index extends Base
{
    public function index()
    { 
        // 实例 获取openid
        $token=input('token');
        $redis = new Redis();
        $result= $redis->get($token);
       if ($result) {
           die(
        json_encode(
            array(
            'code' => 200,
             'data'=>$result,
            'msg' => '数据请求成功'
        ),480)
);
       } else {
           die(
        json_encode(
            array(
            'code' => 100,
            'data'=>'',
            'msg' => 'token失效或不存在!请重新获取'
        ),480)
);
       }
       
      
    
       
    }
}
提出正确的要求

如果后面加一个1

thinkphp5 redis补充
$redis->set('name','value','3600');//添加记录前两个分别表示名和值,后者单位秒
$redis->get($session_key);//根据名查询值
总结
以上就是今天的uniapp结合微信小程序自带Token请求接口的无感知登录解决方案,喜欢的话记得收藏哦!

 
上一篇 
  
        