这里只是做一个记录,虽然网上有很多文章了。我这边做个记录保存一下
首先我们先确定要干什么。公众号网页开发,有的时候需要获取用户信息。而微信自己已经有非常完备的用户系统,所以我们自己做网页要获取用户信息就可以舍去用户名密码登录直接用微信那一边的登录。
参考链接:微信网页开发—网页授权
流程图:
注意微信这边的文档一定要好好看,一般出了问题都是微信这边的文档没有好好看。一定要好好看,即使微信这边文档写得烂也是参考性文章,一定要仔细看
好的,接下开始写代码
一、在配置文件里面记录公众号AppID和公众号AppSecret
文件位置:application/config.php
//微信公众号配置
'wechat' =>[
// 微信公众号APPID
'AppId' => "公众号appid",
// 微信公众号APPIDsecert
'AppSecret' => "公众号appsecret",
]
二、新建一个Wechat类
这边直接贴代码吧,注释都写代码里面了
文件位置:application/index/controller/Wechat.php
<?php
/**
* Created by PhpStorm.
* User: Administrator
* Date: 2020/1/9 0009
* Time: 22:07
*/
namespace app\index\controller;
use think\Config;
use think\Controller;
use think\Request;
use think\Session;
class Wechat extends Controller
{
//前置操作
protected $beforeActionList = [
'login'
];
/**
* 登录检测
*/
public function login()
{
$openid = Session::get('openid');
$wx_config = Config::get('wechat');
$request = Request::instance();
if (!isset($_GET['code']) && empty($openid)) {
//存储回调链接
Session::set('url', $request->url(true));
//引导用户进入授权页面同意授权,获取code
$this->OAuthCode($wx_config['AppId'], $request->url(true));
} else if (isset($_GET['code'])) {
//获取CODE后去获取令牌
//获取access_token和openid
$user_info = $this->OAuthAccess($wx_config['AppId'], $wx_config['AppSecret'], $_GET['code']);
//判断是否返回openid
if(isset($user_info['openid'])){
//获取access_token
$access_token = $user_info['access_token'];//获取access_token对应的值
//获取openid
$openid = $user_info['openid'];//获取openid对应的值
Session::set('openid', $openid);//设置session
//非静默登录可以获取详细用户信息
if($user_info['scope'] == 'snsapi_userinfo'){
$user_detail_info = $this->getUserInfo($access_token, $openid);
if(count($user_detail_info) > 0){
// 取出用户信息
//$user_openid = $user_detail_info['openid'];
//$user_nickname = $user_detail_info['nickname'];
//$user_sex = $user_detail_info['sex'];
//$user_province = $user_detail_info['province'];
//$user_city = $user_detail_info['city'];
//$user_headimgurl = $user_detail_info['headimgurl'];
Session::set('user_detail', $user_detail_info);
}
}
//获取回调链接
$redirect_uri = Session::get('url');
Session::delete('url');
//跳转到初始页面
$this->redirect($redirect_uri, '302');
}
}
}
/**
* 通过调整换取OAuth_Code
*
* @param $appid 公众号AppID
* @param $redirect_uri 回调地址
* @return bool
*/
public function OAuthCode($appid, $redirect_uri)
{
$scope = 'snsapi_userinfo';//用户授权登录
// $scope = 'snsapi_base';//静默登录
header("Location: https://open.weixin.qq.com/connect/oauth2/authorize?appid={$appid}&redirect_uri={$redirect_uri}&response_type=code&scope={$scope}#wechat_redirect");
return true;
}
/**
* 获取access_token和openid
*
* @param $appid 公众号AppID
* @param $appsecret 公众号APPSecret
* @param $code 授权CODE
* @return mixed 返回包含access_token和openid的数组
* {
"access_token":"ACCESS_TOKEN", //网页授权接口调用凭证,注意:此access_token与基础支持的access_token不同
"expires_in":7200, //access_token接口调用凭证超时时间,单位(秒)
"refresh_token":"REFRESH_TOKEN", //用户刷新access_token
"openid":"OPENID", //用户唯一标识
"scope":"SCOPE" //用户授权的作用域,使用逗号(,)分隔
}
*/
public function OAuthAccess($appid, $appsecret, $code)
{
//生成请求连接
$url = "https://api.weixin.qq.com/sns/oauth2/access_token?appid={$appid}&secret={$appsecret}&code={$code}&grant_type=authorization_code";
//服务器端请求微信服务器
$result = $this->httpRequest($url);
//对返回结果进行json_decode解析
$return_array = json_decode($result, true);
//尝试捕获微信返回的错误信息
$this->getWechatError($return_array);
//返回微信返回数据
return $return_array;
}
/**
* 通过access_token和openid换取用户信息
*
* @param $access_token 用户AccessToken
* @param $openid 用户OpenId
* @return mixed 返回信息示范
* {
"openid":" OPENID", //用户的唯一标识
"nickname": NICKNAME, //用户昵称
"sex":"1", //用户的性别,值为1时是男性,值为2时是女性,值为0时是未知
"province":"PROVINCE", //用户个人资料填写的省份
"city":"CITY", //普通用户个人资料填写的城市
"country":"COUNTRY", //国家,如中国为CN
"headimgurl":"url", //用户头像,最后一个数值代表正方形头像大小
(有0、46、64、96、132数值可选,0代表640*640正方形头像),
用户没有头像时该项为空。若用户更换头像,原有头像URL将失效。
"privilege":[ "PRIVILEGE1" "PRIVILEGE2" ], //用户特权信息,json 数组,如微信沃卡用户为(chinaunicom)
"unionid": "o6_bmasdasdsad6_2sgVt7hMZOPfL" //只有在用户将公众号绑定到微信开放平台帐号后,才会出现该字段。
}
*/
public function getUserInfo($access_token, $openid)
{
//生成请求连接
$url = "https://api.weixin.qq.com/sns/userinfo?access_token={$access_token}&openid={$openid}&lang=zh_CN";
//服务器端请求微信服务器
$result = $this->httpRequest($url);
//对返回结果进行json_decode解析
$return_array = json_decode($result, true);
//尝试捕获微信返回的错误信息
$this->getWechatError($return_array);
//返回微信返回数据
return $return_array;
}
/**
* 刷新access_token(如果需要)
*
* @param $appid 公众号AppID
* @param $refresh_token 获取到的refresh_token
* @return mixed 返回结果示范
* {
"access_token":"ACCESS_TOKEN", //网页授权接口调用凭证,注意:此access_token与基础支持的access_token不同
"expires_in":7200, //access_token接口调用凭证超时时间,单位(秒)
"refresh_token":"REFRESH_TOKEN", //用户刷新access_token
"openid":"OPENID", //用户唯一标识
"scope":"SCOPE" //用户授权的作用域,使用逗号(,)分隔
}
*/
public function refreshAccess($appid, $refresh_token)
{
//生成请求连接
$url = "https://api.weixin.qq.com/sns/oauth2/refresh_token?appid={$appid}&grant_type=refresh_token&refresh_token={$refresh_token}";
//服务器端请求微信服务器
$result = $this->httpRequest($url);
//对返回结果进行json_decode解析
$return_array = json_decode($result, true);
//尝试捕获微信返回的错误信息
$this->getWechatError($return_array);
//返回微信返回数据
return $return_array;
}
/**
* 检验授权凭证(access_token)是否有效
*
* @param $access_token
* @param $openid
* @return bool
*/
public function checkAccessValid($access_token, $openid)
{
//生成请求连接
$url = "https://api.weixin.qq.com/sns/auth?access_token={$access_token}&openid={$openid}";
//服务器端请求微信服务器
$result = $this->httpRequest($url);
//对返回结果进行json_decode解析
$return_array = json_decode($result, true);
//确认access_token是否过期
if($return_array['errcode'] == 0){
return true;
} else {
return false;
}
}
/**
* CURL请求
* @date 2018/1/31
* @param $url string
* @return mixed json
*/
public function httpRequest($url)
{
$curl = curl_init();
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_TIMEOUT, 500);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($curl, CURLOPT_URL, $url);
$res = curl_exec($curl);
curl_close($curl);
return $res;
}
/**
* 捕获微信返回的错误信息
*
* @param $result
*/
private function getWechatError($result)
{
if(isset($result['errcode'])){
echo $result['errmsg'];exit;
}
}
}
只要哪个控制器需要登录就可以继承这个类。我这里图省事把登录相关代码function login()也写在了Wechat类里面了。其实可以自由发挥的。最后也是把用户信息存在Session里面了这里也可以做拓展。可以在后面直接写一个新建用户的操作
三、需要登录的控制器相关代码
php代码
文件位置:application/index/controller/Index.php
<?php
namespace app\index\controller;
use think\Config;
use think\Request;
use think\Session;
class Index extends Wechat
{
public function index()
{
//直接从session里面获取到用户信息
$this->assign('user_detail', Session::get('user_detail'));
return view();
}
}
前端H5代码
文件位置:application/index/view/index/index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, height=device-height, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black">
<title>微信用户</title>
</head>
<body>
<img src="{$user_detail['headimgurl']}">
<p>姓名:{$user_detail['nickname']}</p>
<p>openid:{$user_detail['openid']}</p>
<p>性别:{$user_detail['sex']}</p>
<p>所在省:{$user_detail['province']}</p>
<p>所在市:{$user_detail['city']}</p>
</body>
</html>