一、首先当我们借助小程序实现我们的网站搭建时,就需要使用小程序自带的一些功能;且需要根据该小程序获取到的一些参数存储到对应的数据库中。
openID:每个微信用户使用该小程序时都会产生一个openID,且该openID是唯一标识,因此可将其存储在用户表中。
token:这个token值是我们自己在内部生成的,主要是为了安全获取UID,UID在数据库中存储中的是数据记录的唯一ID,如果单纯的传入UID值来获取
该UID的信息值的话,会不安全,因此需要通过token来获取,如何获取我会提供一系列代码;
//随意生成的TOKEN值
public static function generateToken(){ $randChar = getRandChar(32); $timestamp = $_SERVER['REQUEST_TIME_FLOAT']; $tokenSalt = config('secure.salt'); return md5($randChar . $timestamp . $tokenSalt); } public static function verifyToken($token) { $exist = Cache::get($token); if($exist){ return true; } else{ return false; } } //获取以token为键值的部分,获取对应的值 public static function getCurrentTokenVar($key) { $request=Request::instance(); $token = input("token"); if($token==""){ $token=$request->header("token"); } $vars = Cache::get($token); if (!$vars) { throw new TokenException(); } else { if(!is_array($vars)) { $vars = json_decode($vars, true); } if (array_key_exists($key, $vars)) { return $vars[$key]; } else{ // throw new Exception('尝试获取的Token变量并不存在'); return false; } } }
function __construct($code) { $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); } /* * 登录 */ public function get(){ $result = curl_get($this->wxLoginUrl); // 注意json_decode的第一个参数true // 这将使字符串被转化为数组而非对象 $wxResult = json_decode($result, true); if (empty($wxResult)) { // 为什么以empty判断是否错误,这是根据微信返回 // 规则摸索出来的 // 这种情况通常是由于传入不合法的code throw new Exception('获取session_key及openID时异常,微信内部错误'); } else { // 建议用明确的变量来表示是否成功 // 微信服务器并不会将错误标记为400,无论成功还是失败都标记成200 // 这样非常不好判断,只能使用errcode是否存在来判断 $loginFail = array_key_exists('errcode', $wxResult); if ($loginFail) { $this->processLoginError($wxResult); } else { return $this->grantToken($wxResult); } } } //颁发令牌 private function grantToken($wxResult) { // 此处生成令牌使用的是TP5自带的令牌 // 如果想要更加安全可以考虑自己生成更复杂的令牌 // 比如使用JWT并加入盐,如果不加入盐有一定的几率伪造令牌 // $token = Request::instance()->token('token', 'md5'); $openid = $wxResult['openid']; $user = User::getByOpenID($openid); if (!$user) // 借助微信的openid作为用户标识 // 但在系统中的相关查询还是使用自己的uid { $uid = $this->newUser($openid); $type=0; } else { $uid = $user->id; $type=$user->type; } $cachedValue = $this->prepareCachedValue($wxResult, $uid,$type); $token = $this->saveToCache($cachedValue); return $token; } private function processLoginError($wxResult) { throw new WeChatException( [ 'msg' => $wxResult['errmsg'], 'errorCode' => $wxResult['errcode'] ]); } /**创建一个新用户 * @param $openid * @return mixed */ private function newUser($openid) { // 有可能会有异常,如果没有特别处理 // 这里不需要try——catch // 全局异常处理会记录日志 // 并且这样的异常属于服务器异常 // 也不应该定义BaseException返回到客户端 $user = User::create( [ 'openid' => $openid ]); return $user->id; } /**准备存入缓存的数据 * @param $wxResult * @param $uid * @return mixed */ private function prepareCachedValue($wxResult, $uid,$type) { $cachedValue = $wxResult; $cachedValue['uid'] = $uid; $cachedValue['type']=$type; $cachedValue['scope'] =config("secure.user");; return $cachedValue ; } /** * 存入缓存 */ private function saveToCache($wxResult) { $key = self::generateToken(); $value = json_encode($wxResult); $expire_in = config('secure.time'); $result = cache($key, $value, $expire_in); if (!$result){ throw new TokenException([ 'msg' => '服务器缓存异常', 'errorCode' => 10005 ]); } return $key; }
二、当获取到token时,需要在小程序的缓存中也存入该token值;
wx.setStorageSync('token', res.data.token);
使用小程序请求数据时,将token的值存入Header中,后台获取到Token的值,会进行相应的处理,获取到对应的UID