laravel+guzzle微信网页授权登录

1 第一步:用户同意授权,获取code

2 第二步:通过code换取网页授权access_token

3 第三步:刷新access_token(如果需要)

4 第四步:拉取用户信息(需scope为 snsapi_userinfo)

1.因为没有直接操作公众号。所以在建立了视图login.为了调起用户授权,获取code


<html>
    <head>
        <title>login</title>
    </head>
    <body>
        <div class="container">
            <input type="button" name="login" id="login" value="登录">
        </div>
        <script src="{{asset('js/jquery-1.10.2.min.js')}}"></script>
        <script>
            function getUrlParam(name) {

                var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)");
                var r = window.location.search.substr(1).match(reg);
                if (r != null) return unescape(r[2]);
                return null;
            }

            $('#login').click(function (callback) {
                var appId = 'wxdecc14c9870858d6';
                var oauth_url = 'http://wxfuwuhao.jamyooo.com/api/page/testindex';
                var url = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=" + appId + "&redirect_uri=" + oauth_url + "&response_type=code&scope=snsapi_userinfo&state=STATE#wechat_redirect"

                // https://open.weixin.qq.com/connect/oauth2/authorize?appid=wxdecc14c9870858d6&redirect_uri=http://wxfuwuhao.jamyooo.com/api/page/testindex&response_type=code&scope=snsapi_userinfo&state=STATE#wechat_redirect

                var code = getUrlParam("code");
                if (!code) {
                    window.location = url;
                }
                else {
                    console.log(code);
                    $.ajax({
                        type: 'POST',
                        url: oauth_url,
                        dataType: 'json',
                        data: {
                            code: code
                        },
                        success: function (data) {
                            if (data.code === 200) {
                                callback(data.data)
                            }
                        },
                        error: function (error) {
                            throw new Error(error)
                        }
                    })
                }
            })
        </script>
    </body>
</html>
2.安装guzzle依赖详细查看http://guzzle-cn.readthedocs.io/zh_CN/latest/overview.html#installation;
3.获取access_token与openid;
private function Token($code){

        $appId = env('WECHAT_OFFICIAL_ACCOUNT_APPID');
        $secret = env('WECHAT_OFFICIAL_ACCOUNT_SECRET');

        $url = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=".$appId."&secret=".$secret."&code=".$code."&grant_type=authorization_code";

        $client = new GuzzleClient();

        $response = $client->get($url);

        $Tokendata =json_decode($response->getBody()->getContents());

        $token = $Tokendata->access_token;
        //echo token会报错
        echo "<p style='display: none;'>".$token."</p>";

        $openid = $Tokendata->openid;
        $comp = compact('token','openid');
        return $comp;

    }
//获取用户数据
 public function testindex(Request $request){
        $code = $request->code;
        //获取Token返回数据
        $comp =  $this->Token($code);

        $token = $comp['token'];
        $openid = $comp['openid'];

        $userinfo_url ="https://api.weixin.qq.com/sns/userinfo?access_token=".$token."&openid=".$openid."&lang=zh_CN";

        $client = new GuzzleClient();

        $response = $client->get($userinfo_url);
        $userinfo = json_decode($response->getBody()->getContents());
//        dd($userinfo);
        $unionid = $userinfo->unionid;
        $nickname = $userinfo->nickname;
        $sex = $userinfo->sex;
        $headimgurl = $userinfo->headimgurl;
//        echo "<p style='display: none;'>".$unionid.$sex.$nickname.$headimgurl."</p>";

        //判断数据是否存在用户
        $check_user = User::where('openId', $openid)->first();
        if (empty($check_user)){
            //不存在则存入用户数据
            $user = new User();
            $user->openId = $openid;
            $user->unionId = $unionid;
            $user->nickName = $nickname;
            $user->sex = $sex;
            $user->avatar = $headimgurl;
            $user->save();
            return response()->json([
                'status'=>1000,
                'msg'=>'success',
            ]);
        }else{
            return response()->json([
               'status'=>1001,
               'msg'=>'用户'.$nickname.'已存在',
            ]);
        }

    }

遇到的坑:

1.login的路由不能在微信开发工具调试,因为不能触发登录回调。需要把微信开发工具授权登录页的路由复制到微信客户端访问。

2.不知道是微信api的问题还是laravel dd()输出的原因。function Token()中

 $Tokendata =json_decode($response->getBody()->getContents());

这里有个bug:dd()输出的话,在苹果机中是可以打印出完整信息。但是在安卓机中一直显示code已经被使用。但是使用echo ,print_r()输出。无论在苹果机中还是安卓机中都是可以打印出完整的信息。所以在function Token()中需要加上以下语句。否则显示stdClass错误,原因不详。

echo "<p style='display: none;'>".$token."</p>";

 




猜你喜欢

转载自blog.csdn.net/qq_34332656/article/details/80931435