微信小程序登錄demo

class Token
{
	use Send;

	/**
	 * 請求時間差
	 */
	public static $timeDif = 10000;

	public static $accessTokenPrefix = 'accessToken_';
	public static $refreshAccessTokenPrefix = 'refreshAccessToken_';
	public static $expires = 7200;
	public static $refreshExpires = 60*60*24*30;   //刷新token過期時間
	/**
	 * 測試appid,正式請數據庫進行相關驗證
	 */
	public static $appid = 'tp5restfultest';
	/**
	 * appsercet
	 */
	public static $appsercet = '123456';

	/**
	 * 生成token
	 */
	public function token(Request $request)
	{
		//參數驗證
		$validate = new \app\api\validate\Token;
		if(!$validate->check(input(''))){
			return self::returnMsg(401,$validate->getError());
		}
		self::checkParams(input(''));  //參數校驗
		//數據庫已經有一個用戶,這裏需要根據input('mobile')去數據庫查找有沒有這個用戶
		$userInfo = [
			'uid'   => 1,
			'mobile'=> input('mobile')
		]; //虛擬一個uid返回給調用方
		try {
			$accessToken = self::setAccessToken(array_merge($userInfo,input('')));  //傳入參數應該是根據手機號查詢改用戶的數據
			return self::returnMsg(200,'success',$accessToken);
		} catch (Exception $e) {
			return self::returnMsg(500,'fail',$e);
		}
	}

	public function getOpenId($code = '',$encryptedData = '',$iv = '',$appInfo = [])
	{	
        $result = json_decode(file_get_contents("https://api.weixin.qq.com/sns/jscode2session?appid=" . $appInfo['wx_appid'] . "&secret=" . $appInfo['wx_appsercet'] . "&js_code=" . $code . "&grant_type=authorization_code"), true);
		if(empty($result['session_key'])){
			return $this->returnmsg(401,'獲取token失敗!'.$result['errmsg']);
		}else{
            $pc = new wxBizDataCrypt($appInfo['wx_appid'], $result['session_key']);
            $data = $pc->decryptData($encryptedData, $iv); //解密用戶基礎信息
            $data = json_decode($data, true);
            if (!empty($data['openId'])) {
                if (isset($data['unionId'])) { //含有unionid
                    $is_unionid['is_unionid'] = true;
                    $userInfo = WechatFans::get(['unionid' => $data['unionId']]); //按照unionid查找
                    if(empty($userInfo)){
                        $userInfo = WechatFans::get(['openid' => $data['openId']]); //按照openid查找
                    }
                } else {
                    $is_unionid['is_unionid'] = false;
                    $userInfo = WechatFans::get(['openid' => $data['openId']]); //按照openid查找
                }
                $userAdd['openid']     = $data['openId'];
                $userAdd['unionid']    = isset($data['unionId']) ? $data['unionId'] : '';
                $userAdd['nickname']   = $data['nickName'];
                $userAdd['avatar']     = $data['avatarUrl'];
                $userAdd['sex']        = $data['gender'];
                $userAdd['province']   = $data['province'];
                $userAdd['country']    = $data['country'];
                $userAdd['updatetime'] = time();
				if(empty($userInfo)){   //用戶沒有在fans表裏面
                    $userAdd['createtime'] = $userAdd['updatetime'];
                    $userAdd['subscribe_scene'] = 'WEIXIN';
                    $userAdd['source'] = 2;
                    WechatFans::create($userAdd);  //插入到粉絲表
				}else{
					WechatFans::where('id',$userInfo['id'])->update($userAdd);
                    $userAdd['uid'] = $userInfo['uid'];
				}
				return $userAdd;
			}else{
				return $this->returnmsg(401,'獲取token失敗!解析數據失敗');
			}
		}

	}

	/**
	 * 刷新token
	 */
	public function refresh($refresh_token='',$appid = '')
	{
		$cache_refresh_token = Cache::get(self::$refreshAccessTokenPrefix.$appid);  //查看刷新token是否存在
		if(!$cache_refresh_token){
			return self::returnMsg(401,'fail','refresh_token is null');
		}else{
			if($cache_refresh_token !== $refresh_token){
				return self::returnMsg(401,'fail','refresh_token is error');
			}else{    //重新給用戶生成調用token
				$data['appid'] = $appid;
				$accessToken = self::setAccessToken($data); 
				return self::returnMsg(200,'success',$accessToken);
			}
		}
	}

	/**
	 * 參數檢測
	 */
	public static function checkParams($params = [])
	{	
		//時間戳校驗
		if(abs($params['timestamp'] - time()) > self::$timeDif){

			return self::returnMsg(401,'請求時間戳與服務器時間戳異常','timestamp:'.time());
		}

		//appid檢測,這裏是在本地進行測試,正式的應該是查找數據庫或者redis進行驗證
		if($params['appid'] !== self::$appid){
			return self::returnMsg(401,'appid 錯誤');
		}

		//簽名檢測
		$sign = Oauth::makeSign($params,self::$appsercet);
		if($sign !== $params['sign']){
			return self::returnMsg(401,'sign錯誤','sign:'.$sign);
		}
	}

	/**
     * 設置AccessToken
     * @param $clientInfo
     * @return int
     */
    protected function setAccessToken($clientInfo)
    {
        //生成令牌
        $accessToken = self::buildAccessToken();
        $refresh_token = self::getRefreshToken($clientInfo['appid']);

        $accessTokenInfo = [
            'access_token'  => $accessToken,//訪問令牌
            'expires_time'  => time() + self::$expires,      //過期時間時間戳
            'refresh_token' => $refresh_token,//刷新的token
            'refresh_expires_time'  => time() + self::$refreshExpires,      //過期時間時間戳
            'client'        => $clientInfo,//用戶信息
        ];
        self::saveAccessToken($accessToken, $accessTokenInfo);  //保存本次token
        self::saveRefreshToken($refresh_token,$clientInfo['appid']);
        return $accessTokenInfo;
    }

    /**
     * 刷新用的token檢測是否還有效
     */
    public static function getRefreshToken($appid = '')
    {
    	return Cache::get(self::$refreshAccessTokenPrefix.$appid) ? Cache::get(self::$refreshAccessTokenPrefix.$appid) : self::buildAccessToken(); 
    }

    /**
     * 生成AccessToken
     * @return string
     */
    protected static function buildAccessToken($lenght = 32)
    {
        //生成AccessToken
        $str_pol = "1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ123456789abcdefghijklmnopqrstuvwxyz";
		return substr(str_shuffle($str_pol), 0, $lenght);

    }

    /**
     * 存儲token
     * @param $accessToken
     * @param $accessTokenInfo
     */
    protected static function saveAccessToken($accessToken, $accessTokenInfo)
    {
        //存儲accessToken
        cache(self::$accessTokenPrefix . $accessToken, $accessTokenInfo, self::$expires);
    }

    /**
     * 刷新token存儲
     * @param $accessToken
     * @param $accessTokenInfo
     */
    protected static function saveRefreshToken($refresh_token,$appid)
    {
        //存儲RefreshToken
        cache(self::$refreshAccessTokenPrefix.$appid,$refresh_token,self::$refreshExpires);
    }
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章