2 第二步:通过code换取网页授权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>";