* @version : Huosdk 8.0 */ namespace huolib\oauth\driver; use huo\controller\common\CommonFunc; use huolib\constant\CacheConst; use huolib\oauth\OAuth; use huolib\tool\Http; use think\Cache; use think\Exception; class Mp extends OAuth { /** * 获取requestCode的api接口 * * @var string */ protected $request_code_url = 'https://open.weixin.qq.com/connect/oauth2/authorize'; /** * 获取Access token的api接口 * * @var String */ protected $access_token_url = 'https://api.weixin.qq.com/sns/jscode2session'; /** * 更新Access token的api接口 * * @var String */ protected $refresh_token_url = 'https://api.weixin.qq.com/sns/jscode2session'; /** * API根路径 * * @var string */ protected $api_base = 'https://api.weixin.qq.com/sns/'; /** * 获取request_code的额外参数 URL查询字符串格式 * * @var string */ protected $authorize = 'snsapi_userinfo'; /** * Weixin constructor. * * @param array $config * @param array|null $token * * @throws \think\Exception */ public function __construct(array $config = [], array $token = null) { $_config = $config; if (empty($config)) { if (file_exists(GLOBAL_CONF_PATH."extra/oauth/weixin.php")) { $_config = include GLOBAL_CONF_PATH."extra/oauth/weixin.php"; } else { $_config = array(); } } parent::__construct($_config, $token); } /** * * 第一步:请求CODE 跳转URL * 请求Authorize访问地址 * * @param string $display * * @return string 跳转地址 */ public function getRequestCodeUrl($display = 'pc') { $params = array( 'appid' => $this->app_key, 'redirect_uri' => $this->callback, 'response_type' => $this->response_type, 'scope' => $this->authorize, 'state' => $this->getState(), ); return $this->request_code_url.'?'.http_build_query($params).'#wechat_redirect'; } /** * 第二步:通过code获取access_token * code2Session * * @param $code * @param null $extend * * @return array|null * @throws Exception */ public function getAccessToken($code, $extend = null) { $_cache_key = CacheConst::CACHE_SESSION_KEY_PREFIX . $code; $_data = Cache::get($_cache_key); if (!empty($_data)) return json_decode($_data, true); $_params = array( 'appid' => $this->app_key, 'secret' => $this->app_secret, 'grant_type' => $this->grant_type, 'js_code' => $code, ); $_rdata = Http::get($this->access_token_url, $_params); $this->token = $this->parseToken($_rdata); Cache::set($_cache_key, json_encode($this->token), 300); return $this->token; } /** * 刷新access_token有效期 * * @param $refresh_token * * @return array|mixed|null * @throws Exception */ public function getRefreshAccessToken($refresh_token) { $_params = array( 'appid' => $this->app_key, 'refresh_token' => $refresh_token, 'grant_type' => $this->grant_type, ); $_rdata = Http::get($this->refresh_token_url, $_params); $this->token = $this->parseToken($_rdata); return $this->token; } /** * 第三步:通过access_token调用接口 * * @param string $api API * @param string $param 调用API的额外参数 * @param string $method HTTP请求方法 默认为GET * @param null $multi * * @return mixed * @throws Exception */ public function call($api, $param = '', $method = 'GET', $multi = null) { $params = array( 'access_token' => $this->token['access_token'], 'openid' => $this->getOpenid(), 'lang' => 'zh_CN' ); $data = Http::request($this->url($api), $params, $method); return json_decode($data, true); } /** * 获取授权用户的用户信息 * * @return array * @throws \Exception * https://open.weixin.qq.com/cgi-bin/showdocument?action=dir_list&t=resource/res_list&verify=1&id=open1419316518&lang=zh_CN * * openid 普通用户的标识,对当前开发者帐号唯一 * nickname 普通用户昵称 * sex 普通用户性别,1为男性,2为女性 * province 普通用户个人资料填写的省份 * city 普通用户个人资料填写的城市 * country 国家,如中国为CN * headimgurl 用户头像,最后一个数值代表正方形头像大小(有0、46、64、96、132数值可选,0代表640*640正方形头像),用户没有头像时该项为空 * privilege 用户特权信息,json数组,如微信沃卡用户为(chinaunicom) * unionid 用户统一标识。针对一个微信开放平台帐号下的应用,同一用户的unionid是唯一的。 * */ public function getUserInfo() { $_oauth_data = array( 'openid' => $this->token['openid'], 'unionid' => isset($this->token['unionid']) ? $this->token['unionid'] : '', 'channel' => 'mp', 'nickname' => '', 'gender' => '', 'avatar' => '', 'token' => $this->token ); return $_oauth_data; } /** * 获取当前授权用户的SNS标识 * * @throws Exception */ public function getOpenid() { $_data = $this->token; if (isset($_data['openid'])) { return $_data['openid']; } else { throw new Exception('没有获取到微信用户ID!'); } } /** * @param string $refresh_token * * @return array */ protected function getRefreshParam($refresh_token = '') { $_params = array( 'appid' => $this->app_key, 'grant_type' => 'refresh_token', 'refresh_token' => $refresh_token, ); return $_params; } /** * 解析access_token方法请求后的返回值 * * @param $result * @param null $extend * * @return mixed * @throws Exception */ protected function parseToken($result, $extend = null) { $_rdata = json_decode($result, true); if (!empty($_rdata) && !empty($_rdata['session_key']) && !empty($_rdata['openid'])) { $_rdata['access_token'] = $_rdata['session_key']; $_rdata['expires_in'] = 0; $_rdata['unionid'] = isset($_rdata['unionid']) ? $_rdata['unionid'] : ''; if (empty($_rdata['unionid'])) { $_rdata['unionid'] = CommonFunc::getUnionIdByEncryptedData($this->app_key, $_rdata['session_key']); } if (empty($_rdata['unionid'])) { $_rdata['unionid'] = $_rdata['openid']; } unset($_rdata['session_key']); $this->token = $_rdata; $_rdata['openid'] = $this->getOpenid(); return $_rdata; } else { throw new Exception("获取微信 ACCESS_token 出错:{$result}"); } } /** * https://developers.weixin.qq.com/minigame/dev/tutorial/open-ability/http-signature.html * */ protected function checkSession($access_token,$openid,$signature,$sig_method){ } }