ThinkPHP5.0token机制

(一开始就被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));
            }
        }
    }

你可能感兴趣的:(ThinkPHP5.0token机制)