小程序token.php,ThinkPHP5.0微信小程序token机制原理

(一开始就被web的session机制搞懵了,结果发现和微信小程序token机制不一样,先感谢下琳姐姐把我从杂乱无章的代码里拯救出来…)

首先小程序登陆的时候会post用户名,密码和微信小程序用户登录时获取的code码到服务端。

然后去获得token,id是user表中与各个账号唯一对应的id,也是通过token验证后要去获得用户的唯一标识,id通过用户名和密码去表中select id获得

//获得token

$tk = $TokenModel->get_token($data['code'],$id);

详细看一下get_token函数

/*

* @ 注册或者登录获取token令牌

* @ $code 小程序获取的code码

*/

public function get_token($code,$id) {

$ut = new UserToken($code);

$token = $ut->gett($code,$id);

return $token;

}

接着看gett函数 首先是一大堆wx的参数去获得sprintf一个网址,判断wxResult的结果,没问题就去取token

public function gett($code,$id){

$this->code = $code;

$this->wxAppID = config('wx.app_id');

$this->wxAppSecret = config('wx.app_secret');

$this->wxLoginurl = sprintf(config('wx.login_url'),

$this->wxAppID,$this->wxAppSecret,$this->code);

$result = curl_get($this->wxLoginurl);

//返回的字符串变成数组,true是数组,false是对象

$wxResult = json_decode($result, true);

if (empty($wxResult)){

throw new Exception('获取session_key及openID时异常,微信内部错误');

}

else{

$loginFail = array_key_exists('errcode',$wxResult);

if ($loginFail){

$this->processLoginError($wxResult);

}else{

//检测没有报错的话就去取token

return $this->grantToken($wxResult,$id);

}

}

}

接着看grantToken函数,经过一大长串的验证id还有检测

public function grantToken($wxResult,$id){

//验证id

(new IDMustBeNumber())->goToCheck([

'id' => $id

]);

//检验id在的时候,这里的openid等于它

$openid = $wxResult['openid'];

$user = Db::table('user')->where([

'id' => $id

])->field('openid')->find();

$user_openid = $user['openid'];

//检测是否绑定

$check_exist = Db::table('user')->where(['openid' => $openid])->find();

if ($check_exist){

if ($check_exist['id'] != $id){

throw new BaseException([

'msg' => '您的微信号已经绑定过一个账号了,不可重复关联!'

]);

}

}

if ($user_openid == NULL){

$integrity = Db::table('user')->where([

'id' => $id

])->update([

'openid' => $openid

]);

if (!$integrity){

throw new BaseException([

'msg' => '您的微信号已经绑定过一个账号了,不可重复关联!'

]);

}

}else{

if ($user_openid != $openid){

throw new LoginException([

'msg' => '微信号与用户账号不匹配!'

]);

}

}

这些都不重要,主要看token的获取,这里的key就是token,用的是32随机+时间戳+salt

获得,保证唯一性而已

public function gettoken(){

//用三组字符串md5加密

//32个字符组成一组随机字符串

$randChars = getRandChars(32);

//时间戳

$timestamp = $_SERVER['REQUEST_TIME_FLOAT'];

//salt 盐

$salt = config('setting.token_salt');

$key = md5($randChars.$timestamp.$salt);

return $key;

}

重点在这

这里直接用了TP的cache机制 ,将token设为Cache的key,用户的id设为value,然后每次前端请求接口的时候只要给我们token,我们就可以获取到用户的id并且拿到他的信息。

通过cache($key, $value, $expire_in)进行缓存

$this->uid = $id;

//这是一个拼接token的函数,32随机+时间戳+salt

//key就是token,value包含uid,scope

//拿到钥匙

$key = $this->gettoken();

$cachedValue['id'] = $id;

//scope为权限

$cachedValue['secret'] = 16;

$this->secret = 16;

$value = json_encode($cachedValue);

//设置存活时间

$expire_in = config('setting.token_expire_in');

//存入缓存

$request = cache($key, $value, $expire_in);

if (!$request){

throw new TokenException([

'msg' => '服务器缓存异常',

]);

}

return $key;

后台缓存好token,客户端请求服务端的时候带上token,后台取校验token并获取id就好啦

public function get_id(){

$token = input('post.token');

$vars = Cache::get($token);

if (!$vars){

exit(json_encode([

'code' => 401,

'msg' => 'Token已经过期或无效Token!'

],JSON_UNESCAPED_UNICODE));

}else{

if (!is_array($vars)){

$vars = json_decode($vars,true);

}

if (array_key_exists('username',$vars)) {

return $vars['username'];

}else{

exit(json_encode([

'code' => 444,

'msg' => '尝试获取的Token变量并不存在!'

],JSON_UNESCAPED_UNICODE));

}

}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值