浅聊使用PHP实现微信公众号登录

微信授权的整体流程

微信授权开发过程

获取微信公众号的AppID和AppSecret

每个公众号都有对应的AppID和AppSecret,可以登录微信公众平台基本配置中的开发者ID可以查看到。当然,这对应的是生产环境,对于那些关注的人数较多的公众号来说,是不会用这个ID来进行测试的。因此,微信公众平台还提供了相应的测试账号。可以通过开发者工具
公众平台测试账号进入(根据不同微信号可以在同一个公众号中建立不同的测试账号)。

首先进入微信公众平台后找到服务器配置

这个服务器地址其实是微信要确认你的服务器是否正确响应它所需要的值
其实微信会使用该接口发起一个请求,参数为:

signature:微信加密签名
echostr:随机字符串
timestamp:时间戳
nonce:随机数

只有在验证URL的时候查询字符串中才会有“echostr”这个字段,验证的方法是

  1. 将token、timestamp、nonce三个参数进行字典序排序
  2. 将三个参数字符串拼接成一个字符串进行sha1加密
  3. 开发者获得加密后的字符串可与signature对比,标识该请求来源于微信

简单来说就是使用固定的排序与加密验证参数后,返回echostr字段值
PS:echostr字段其实是一组数字,如果token还是验证失败的话可以强制转换为数字(我就是这样解决)
贴代码:
使用Yii2框架
控制器

   public function actionToken()
    {
        $params = Yii::$app->request->getQueryParams();
        if(WechatService::instance()->checkSignature()){
            return (int)$params['echostr'];
        }
        return (int)$params['echostr'];
    }

service层

    protected $token;
    public function __construct()
    {
        $this->token = 'weixin';//必须要与微信公众后台填写的token一致
    }

//签名验证程序    ,checkSignature被18行调用。
    //官方加密、校验流程:将token,timestamp,nonce这三个参数进行字典序排序,
    //然后将这三个参数字符串拼接成一个字符串惊喜shal加密,开发者获得加密后的字符串可以与signature对比,表示该请求来源于微信。
    public function checkSignature()
    {
        $signature = $_GET["signature"];//从用户端获取签名赋予变量signature
        $timestamp = $_GET["timestamp"];//从用户端获取时间戳赋予变量timestamp
        $nonce = $_GET["nonce"];  //从用户端获取随机数赋予变量nonce

        $token = $this->token;//将常量token赋予变量token
        $tmpArr = array($token, $timestamp, $nonce);//简历数组变量tmpArr
        sort($tmpArr);//新建排序
        $tmpStr = implode($tmpArr);//字典排序
        $tmpStr = sha1($tmpStr);//shal加密
        //tmpStr与signature值相同,返回真,否则返回假
        if ($tmpStr == $signature) {
            return true;
        } else {
            return false;
        }
    }

拉取微信授权

想要对用户进行授权,其实就是让用户进入下面的授权链接:

https://open.weixin.qq.com/connect/oauth2/authorize?appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=SCOPE&state=STATE#wechat_redirect

微信的授权链接有几部分组成,appidrediect_uriresponse_typescopestatewechat_redirect,这几个参数的传值,在微信的开发文档上都有,现在附上,并添加一些需要注意的地方:

参数 必须 说明
appid 公众号的唯一标识
redirect_uri 授权后重定向的回调链接地址 即需要在用户点击同意授权按钮后返回的页面
response_type 返回类型,请填写code
scope 应用授权作用域,snsapi_base(不弹出授权页面,直接跳转,只能获取用户openid),snsapi_userinfo(弹出授权页面,可通过openid拿到昵称、性别、所在地。并且,即使在未关注的情况下,只要用户授权,也能获取其信息) 建议使用snsapi_userinfo,能够获取更多地信息,同时,当用户已经关注了该公众号的时候,第一次授权会弹出授权页面,而第二次之后则会不弹出,为禁默状态,即用户会感知不到授权页面
state 重定向后会带上state参数,开发者可以填写a-zA-Z0-9的参数值,最多128字节 在state上可以带上页面链接需要的参数,如id号等,可以传入”a=1”这样的键值对,但需要进行转码
#wechat_redirect 直接在微信打开链接,可以不填此参数。做页面302重定向时候,必须带此参数

通过以上参数可以拼接出需要授权访问的页面链接,如下测试链接:

https://open.weixin.qq.com/connect/oauth2/authorize?appid=xxxxxxxx&redirect_uri=http://www.xxxx.com&response_type=code&scope=snsapi_userinfo
&state=abcd#wechat_redirect

当用户点击该链接的时候,微信会弹出授权页面,当用户确认授权后,微信会回调一个http://www.xxxx.com?code=12334566778&state=abcd的页面,在该页面中code是微信返回的一串字符串,且使用一次后即失效。

这个回调就是用户点击确认后会往你填写的redirect_uri链接后面带上参数code和state
这个code我们可以拿来获取access_token

获取access_token

 public function getToken()
    {
		//code是发起授权后得到的code(基本都是前端发起获得该值后传到后端)
        $code = $_GET["code"];
        //通过code获得 access_token + openid
        $url = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=" . $this->appid
            . "&secret=" . $this->secret . "&code=" . $code . "&grant_type=authorization_code";
        $jsonResult = $this->https_request($url);
        $resultArray = json_decode($jsonResult, true);
        if (empty($resultArray)){
            return $this->error(-1,'错误');
        }
        //$resultArray就是获取的相关信息了
        //后面可以写自己的业务逻辑了
    }
    /**
     * 执行curl操作
     * @param $url '执行路由'
     * @param $data '参数'
     * @return bool|string
     */
    public function https_request($url, $data = null)
    {
        $curl = curl_init();
        curl_setopt($curl, CURLOPT_URL, $url);
        curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE);
        curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, FALSE);
        if (!empty($data)) {
            curl_setopt($curl, CURLOPT_POST, 1);
            curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
        }
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
        $output = curl_exec($curl);
        curl_close($curl);
        return $output;
    }

获取到access_token后,就可以去拿用户信息了
获取用户信息需要两个字段
access_token和openid,这两个字段在上面获取access_token就可以拿到了

  /**
     * 保存用户详细信息
     * @param $access_token
     * @param $openid
     * @return appcommoncomponentsResult
     */
    public function getUser($access_token,$openid)
    {

        $cgiToken = $this->getCgiToken();
        $infoUrl = "https://api.weixin.qq.com/sns/userinfo?access_token=" . $access_token . "&openid=" . $openid . '&lang=zh_CN';
        $infoResult = $this->https_request($infoUrl);
        $infoArray = json_decode($infoResult, true);
       //$infoArray是用户信息
    }

版权声明:
作者:linrux
链接:https://www.tot7.cn/technology/php/127.html
来源:Code林
文章版权归作者所有,未经允许请勿转载。

THE END
分享
二维码
< <上一篇
下一篇>>