微信授权登录并获取用户信息接口

广告:宝塔Linux面板高效运维的服务器管理软件 点击【 https://www.bt.cn/p/uNLv1L 】立即购买

微信授权登录并获取用户信息接口

  近排在做微信接口开发,所以总结一下微信授权登录并获取用户信息 这个接口的开发流程。

一、首先你的微信公众号要获得相应的AppID和AppSecret,申请微信登录且通过审核后,才可开始接入流程。

二、授权流程

1、流程说明

(1). 第三方发起微信授权登录请求,微信用户允许授权第三方应用后,微信会拉起应用或重定向到第三方网站,并且带上授权临时票据code参数;

(2). 通过code参数加上AppID和AppSecret等,通过API换取access_token;

(3). 通过access_token进行接口调用,获取用户基本数据资源或帮助用户实现基本操作。

2、获取access_token时序图:

三、开发(我的用是CI框架,其实用什么框架都一样,MVC模式就行了)

1、请求CODE

  weixin.php

<?php    class weixinController extends CI_Controller {        public $userInfo;        public $wxId;        public function __construct(){            parent::__construct();            //只要用户一访问此模块,就登录授权,获取用户信息            $this->userInfo = $this->getWxUserInfo();        }            /**         * 确保当前用户是在微信中打开,并且获取用户信息         *         * @param string $url 获取到微信授权临时票据(code)回调页面的URL         */        private function getWxUserInfo($url = '') {            //微信标记(自己创建的)            $wxSign = $this->input->cookie('wxSign');            //先看看本地cookie里是否存在微信唯一标记,            //假如存在,可以通过$wxSign到redis里取出微信个人信息(因为在第一次取到微信个人信息,我会将其保存一份到redis服务器里缓存着)            if (!empty($wxSign)) {                //如果存在,则从Redis里取出缓存了的数据                $userInfo = $this->model->redisCache->getData("weixin:sign_{$wxSign}");                if (!empty($userInfo)) {                    //获取用户的openid                    $this->wxId = $userInfo['openid'];                    //将其存在cookie里                    $this->input->set_cookie('wxId', $this->wxId, 60*60*24*7);                    return $userInfo;                }            }            //获取授权临时票据(code)            $code = $_GET['code'];            if (empty($code)) {                if (empty($url)) {                    $url = rtirm($_SERVER['QUERY_STRING'], '/');                    //到WxModel.php里获取到微信授权请求URL,然后redirect请求url                    redirect($this->model->wx->getOAuthUrl(baseUrl($url)));                }            }        }    }?>
登录后复制

获取code的Controller代码

  Wxmodel.php

<?php    class WxModel extends ModelBase{        public $appId;        public $appSecret;        public $token;        public function __construct() {            parent::__construct();            //审核通过的移动应用所给的AppID和AppSecret            $this->appId = 'wx0000000000000000';            $this->appSecret = '00000000000000000000000000000';            $this->token = '00000000';        }        /**         * 获取微信授权url         * @param string 授权后跳转的URL         * @param bool 是否只获取openid,true时,不会弹出授权页面,但只能获取用户的openid,而false时,弹出授权页面,可以通过openid获取用户信息         *           */       public function getOAuthUrl($redirectUrl, $openIdOnly, $state = '') {        $redirectUrl = urlencode($redirectUrl);        $scope = $openIdOnly ? 'snsapi_base' : 'snsapi_userinfo';        $oAuthUrl = "https://open.weixin.qq.com/connect/oauth2/authorize?appid={$this->appId}&redirect_uri={$redirectUrl}&response_type=code&scope=$scope&state=$state";        return $oAuthUrl;       }获取code的Model代码
登录后复制

获取code的Model代码

这里附上请求参数说明和返回值说明

  请求参数说明:

  响应返回值说明:

  当请求成功,会redirect到请求参数中的redirect_uri的值中去,其实又回到weixin.php的$this->userInfo = $this->getWxUserInfo();这行去,然后再一次进入到getWxUserInfo()方法,此时

            //获取授权临时票据(code)            $code = $_GET['code'];
登录后复制

这行也已经能获取得到code的值了。接着进行第二步。

2、通过code获取access_token

  weixin.php

<?php    class weixinController extends CI_Controller {        public $userInfo;        public $wxId;        public function __construct(){            parent::__construct();            //只要用户一访问此模块,就登录授权,获取用户信息            $this->userInfo = $this->getWxUserInfo();        }            /**         * 确保当前用户是在微信中打开,并且获取用户信息         *         * @param string $url 获取到微信授权临时票据(code)回调页面的URL         */        private function getWxUserInfo($url = '') {            //微信标记(自己创建的)            $wxSign = $this->input->cookie('wxSign');            //先看看本地cookie里是否存在微信唯一标记,            //假如存在,可以通过$wxSign到redis里取出微信个人信息(因为在第一次取到微信个人信息,我会将其保存一份到redis服务器里缓存着)            if (!empty($wxSign)) {                //如果存在,则从Redis里取出缓存了的数据                $userInfo = $this->model->redisCache->getData("weixin:sign_{$wxSign}");                if (!empty($userInfo)) {                    //获取用户的openid                    $this->wxId = $userInfo['openid'];                    //将其存在cookie里                    $this->input->set_cookie('wxId', $this->wxId, 60*60*24*7);                    return $userInfo;                }            }            //获取授权临时票据(code)            $code = $_GET['code'];            if (empty($code)) {                if (empty($url)) {                    $url = rtirm($_SERVER['QUERY_STRING'], '/');                    //到WxModel.php里获取到微信授权请求URL,然后redirect请求url                    redirect($this->model->wx->getOAuthUrl(baseUrl($url)));                }            }            /***************这里开始第二步:通过code获取access_token****************/            $result = $this->model->wx->getOauthAccessToken($code);            //如果发生错误            if (isset($result['errcode'])) {                return array('msg'=>'授权失败,请联系客服','result'=>$result);            }            //到这一步就说明已经取到了access_token            $this->wxId = $result['openid'];            $accessToken = $result['access_token'];            $openId = $result['openid'];            //将openid和accesstoken存入cookie中            $this->input->set_cookie('wx_id', $this->wxId, 60*60*24*7);            $this->input->set_cookie('access_token', $accessToken);获取access_token的控制器代码
登录后复制

获取access_token的控制器代码

  WxModel.php

<?php    class WxModel extends ModelBase{        public $appId;        public $appSecret;        public $token;        public function __construct() {            parent::__construct();            //审核通过的移动应用所给的AppID和AppSecret            $this->appId = 'wx0000000000000000';            $this->appSecret = '00000000000000000000000000000';            $this->token = '00000000';        }        /**         * 获取微信授权url         * @param string 授权后跳转的URL         * @param bool 是否只获取openid,true时,不会弹出授权页面,但只能获取用户的openid,而false时,弹出授权页面,可以通过openid获取用户信息         *           */        public function getOAuthUrl($redirectUrl, $openIdOnly, $state = '') {            $redirectUrl = urlencode($redirectUrl);            $scope = $openIdOnly ? 'snsapi_base' : 'snsapi_userinfo';            $oAuthUrl = "https://open.weixin.qq.com/connect/oauth2/authorize?appid={$this->appId}&redirect_uri={$redirectUrl}&response_type=code&scope=$scope&state=$state#wechat_redirect";            return $oAuthUrl;        }        /**        * 获取access_token        */        public function getoAuthAccessToken($code) {            return json_decode(file_get_contents("https://api.weixin.qq.com/sns/oauth2/access_token?appid={$this->AppId}&secret={$this->AppSecret}&code={$authCode}&grant_type=authorization_code",true);        }获取access_token的Model代码
登录后复制

获取access_token的Model代码

这里附上参数说明

  请求参数说明:

  响应返回值说明:

  当返回错误时是这样子的:

3、通过access_token调用接口(获取用户信息)  获取access_token后,进行接口调用,有以下前提:

  (1)access_tokec有效且未超时;

  (2)微信用户已授权给第三方应用账号相应的接口作用域(scope)。

 

  以下是获取用户信息的代码

  weixin.php

<?php    class weixinController extends CI_Controller {        public $userInfo;        public $wxId;        public function __construct(){            parent::__construct();            //只要用户一访问此模块,就登录授权,获取用户信息            $this->userInfo = $this->getWxUserInfo();        }            /**         * 确保当前用户是在微信中打开,并且获取用户信息         *         * @param string $url 获取到微信授权临时票据(code)回调页面的URL         */        private function getWxUserInfo($url = '') {            //微信标记(自己创建的)            $wxSign = $this->input->cookie('wxSign');            //先看看本地cookie里是否存在微信唯一标记,            //假如存在,可以通过$wxSign到redis里取出微信个人信息(因为在第一次取到微信个人信息,我会将其保存一份到redis服务器里缓存着)            if (!empty($wxSign)) {                //如果存在,则从Redis里取出缓存了的数据                $userInfo = $this->model->redisCache->getData("weixin:sign_{$wxSign}");                if (!empty($userInfo)) {                    //获取用户的openid                    $this->wxId = $userInfo['openid'];                    //将其存在cookie里                    $this->input->set_cookie('wxId', $this->wxId, 60*60*24*7);                    return $userInfo;                }            }            //获取授权临时票据(code)            $code = $_GET['code'];            if (empty($code)) {                if (empty($url)) {                    $url = rtirm($_SERVER['QUERY_STRING'], '/');                    //到WxModel.php里获取到微信授权请求URL,然后redirect请求url                    redirect($this->model->wx->getOAuthUrl(baseUrl($url)));                }            }            /***************这里开始第二步:通过code获取access_token****************/            $result = $this->model->wx->getOauthAccessToken($code);            //如果发生错误            if (isset($result['errcode'])) {                return array('msg'=>'授权失败,请联系客服','result'=>$result);            }            //到这一步就说明已经取到了access_token            $this->wxId = $result['openid'];            $accessToken = $result['access_token'];            $openId = $result['openid'];            //将openid和accesstoken存入cookie中            $this->input->set_cookie('wx_id', $this->wxId, 60*60*24*7);            $this->input->set_cookie('access_token', $accessToken);            /*******************这里开始第三步:通过access_token调用接口,取出用户信息***********************/            $this->userInfo = $this->model->wx->getUserInfo($openId, $accessToken);            //自定义微信唯一标识符            $wxSign =substr(md5($this->wxId.'k2a5dd'), 8, 16);            //将其存到cookie里            $this->input->set_cookie('wxSign', $wxSign, 60*60*24*7);            //将个人信息缓存到redis里            $this->library->redisCache->set("weixin:sign_{$wxSign}", $userInfo, 60*60*24*7);            return $userInfo;        }    }?>获取用户信息的Controller
登录后复制

获取用户信息的Controller

  WxModel.php

<?php    class WxModel extends ModelBase{        public $appId;        public $appSecret;        public $token;        public function __construct() {            parent::__construct();            //审核通过的移动应用所给的AppID和AppSecret            $this->appId = 'wx0000000000000000';            $this->appSecret = '00000000000000000000000000000';            $this->token = '00000000';        }        /**         * 获取微信授权url         * @param string 授权后跳转的URL         * @param bool 是否只获取openid,true时,不会弹出授权页面,但只能获取用户的openid,而false时,弹出授权页面,可以通过openid获取用户信息         *           */        public function getOAuthUrl($redirectUrl, $openIdOnly, $state = '') {            $redirectUrl = urlencode($redirectUrl);            $scope = $openIdOnly ? 'snsapi_base' : 'snsapi_userinfo';            $oAuthUrl = "https://open.weixin.qq.com/connect/oauth2/authorize?appid={$this->appId}&redirect_uri={$redirectUrl}&response_type=code&scope=$scope&state=$state#wechat_redirect";            return $oAuthUrl;        }        /**        * 获取access_token        */        public function getoAuthAccessToken($code) {            return json_decode(file_get_contents("https://api.weixin.qq.com/sns/oauth2/access_token?appid={$this->AppId}&secret={$this->AppSecret}&code={$authCode}&grant_type=authorization_code",true);        }        /**        * 获取用户信息          */        public function getUserInfo($openId, $accessToken) {            $url = 'https://api.weixin.qq.com/sns/userinfo';            //获取用户微信账号信息            $userInfo = $this->callApi("$url?access_token=$accessToken&openid=$openId&lang=zh-CN");            if ($userInfo['errcode']) {                return array('msg'=>'获取用户信息失败,请联系客服', $userInfo);            }            $userInfo['wx_id'] = $openId;            return $userInfo;        }        /**         * 发起Api请求,并获取返回结果         * @param string 请求URL         * @param mixed 请求参数 (array|string)         * @param string 请求类型 (GET|POST)         * @return array                 */        public function callApi($apiUrl, $param = array(), $method = 'GET') {            $result = curl_request_json($error, $apiUrl, $params, $method);            //假如返回的数组有错误码,或者变量$error也有值            if (!empty($result['errcode'])) {                $errorCode = $result['errcode'];                $errorMsg = $result['errmsg'];            } else if ($error != false) {                $errorCode = $error['errorCode'];                $errorMsg = $error['errorMessage'];            }            if (isset($errorCode)) {                //将其插入日志文件                file_put_contents("/data/error.log", "callApi:url=$apiUrl,error=[$errorCode]$errorMsg");                if ($errorCode === 40001) {                    //尝试更正access_token后重试                    try {                        $pos = strpos(strtolower($url), 'access_token=');                        if ($pos !==false ) {                            $pos += strlen('access_token=');                            $pos2 = strpos($apiUrl, '&' ,$pos);                            $accessTokened = substr($apiUrl, $pos, $pos2 === false ? null : ($pos2 - $pos));                            return $this->callApi(str_replace($accessTokened, $this->_getApiToken(true), $apiUrl), $param, $method);                        }                    }catch (WeixinException $e) {                     }                }                //这里抛出异常,具有的就不详说了                throw new WeixinException($errorMessage, $errorCode);            }            return $result;        }        /**        * 获取微信 api 的 access_token 。 不同于 OAuth 中的 access_token ,参见  http://mp.weixin.qq.com/wiki/index.php?title=%E8%8E%B7%E5%8F%96access_token        *        * @param bool 是否强制刷新 accessToken        */        private function _getApiToken($forceRefresh = false) {            //先查看一下redis里是否已经缓存过access_token            $accessToken = $this->library->redisCache->get('Weixin:AccessToken');            if($forceRefresh || empty($accessToken)) {                $result = $this->callApi("https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={$this->appId}&secret={$this->appSecret}");                $accessToken = $result['access_token'];                $expire = max(1, intval($result['expires_in']) - 60);                //将access_token缓存到redis里去                $this->library->redisCache->set('Weixin:AccessToken', $accessToken, $expire);            }            return $accessToken;        }?>
登录后复制

获取用户信息的Model

  Common.php

<?php    /**     *   发起一个HTTP(S)请求,并返回json格式的响应数据     *   @param array 错误信息  array($errorCode, $errorMessage)     *   @param string 请求Url     *   @param array 请求参数     *   @param string 请求类型(GET|POST)     *   @param int 超时时间     *   @param array 额外配置     *        *   @return array     */     public function curl_request_json(&$error, $url, $param = array(), $method = 'GET', $timeout = 10, $exOptions = null) {        $error = false;        $responseText = curl_request_text($error, $url, $param, $method, $timeout, $exOptions);        $response = null;        if ($error == false && $responseText > 0) {            $response = json_decode($responseText, true);            if ($response == null) {                $error = array('errorCode'=>-1, 'errorMessage'=>'json decode fail', 'responseText'=>$responseText);                //将错误信息记录日志文件里                $logText = "json decode fail : $url";                if (!empty($param)) {                    $logText .= ", param=".json_encode($param);                }                $logText .= ", responseText=$responseText";                file_put_contents("/data/error.log", $logText);            }        }        return $response;    }    /**    *  发起一个HTTP(S)请求,并返回响应文本    *   @param array 错误信息  array($errorCode, $errorMessage)    *   @param string 请求Url    *   @param array 请求参数    *   @param string 请求类型(GET|POST)    *   @param int 超时时间    *   @param array 额外配置    *       *   @return string    */    public function curl_request_text(&$error, $url, $param = array(), $method = 'GET', $timeout = 15, $exOptions = NULL) {        //判断是否开启了curl扩展        if (!function_exists('curl_init')) exit('please open this curl extension');        //将请求方法变大写        $method = strtoupper($method);        $ch = curl_init();        curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $timeout);        curl_setopt($ch, CURLOPT_TIMEOUT, $timeout);        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);        curl_setopt($ch, CURLOPT_HEADER, false);        if (isset($_SERVER['HTTP_USER_AGENT'])) curl_setopt($ch, CURLOPT_USERAGENT, $_SERVER['HTTP_USER_AGENT']);        if (isset($_SERVER['HTTP_REFERER'])) curl_setopt($ch, CURLOPT_REFERER, $_SERVER['HTTP_REFERER']);        curl_setopt($ch, CURLOPT_AUTOREFERER, 1);        switch ($method) {            case 'POST':                curl_setopt($ch, CURLOPT_POST, true);                if (!empty($param)) {                    curl_setopt($ch, CURLOPT_POSTFIELDS, (is_array($param)) ? http_build_query($param) : $param);                }                break;                        case 'GET':            case 'DELETE':                if ($method == 'DELETE') {                    curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'DELETE');                }                if (!empty($param)) {                    $url = $url.(strpos($url, '?') ? '&' : '?').(is_array($param) ? http_build_query($param) : $param);                }                break;        }        curl_setopt($ch, CURLINFO_HEADER_OUT, true);        curl_setopt($ch, CURLOPT_URL, $url);        //设置额外配置        if (!empty($exOptions)) {            foreach ($exOptions as $k => $v) {                curl_setopt($ch, $k, $v);            }        }        $response = curl_exec($ch);        $error = false;        //看是否有报错        $errorCode = curl_errno($ch);        if ($errorCode) {            $errorMessage = curl_error($ch);            $error = array('errorCode'=>$errorCode, 'errorMessage'=>$errorMessage);            //将报错写入日志文件里            $logText = "$method $url: [$errorCode]$errorMessage";            if (!empty($param)) $logText .= ",$param".json_encode($param);            file_put_contents('/data/error.log', $logText);        }        curl_close($ch);        return $response;    }?>
登录后复制

获取用户信息的自定义函数

  

通过以上三步调用接口,就可以获取到用户的微信账号信息了。

大家可以认真看看代码, 里面很多地方我都带上了注释,很容易理解。希望想学习的朋友可以认真看看。

更多微信授权登录并获取用户信息接口相关文章请关注PHP中文网!

广告:SSL证书一年128.66元起,点击购买~~~

9543建站博客
一个专注于网站开发、微信开发的技术类纯净博客。
作者头像
admin创始人

肥猫,知名SEO博客站长,14年SEO经验。

上一篇:浅析小程序中怎么让scroll-view按照指定位置滚动
下一篇:Bootstrap table中toolbar新增条件查询及refresh参数使用方法

发表评论

关闭广告
关闭广告