假设有两个公众号A和B, 怎样在B公众号的项目里面判断用户时候关注了A公众号,
1.需要将两个公众号绑定在同一个微信开放平台下面, 同一个开放平台会给用户统一的unionid, 而不同的公众号openid不同,
这时unionid就是连接两个不同公众号相同粉丝的唯一纽带
2.登录B项目的时候授权A的微信
Controller部分
/**
* B调用A部分
*/
//微信浏览器,用户自动登录,并重新定向 附带code参数
// back_url 经过urlencode的回跳地址
public function get_user_code(){
$back_url = I("redirect_uri","","urldecode");
$password = I("password","","trim");
$WxUsersModel = D('WxUsers');
$result = $WxUsersModel->getCode($back_url,$password);
if(isset($result['code']) && isset($result['lexer'])){
$url = $result['lexer'];
$url_replace=preg_replace('/(.*)(?|&)code=[^&]+?(&)(.*)/i','$1$2$4',$url.'&');
$url_substr=substr($url_replace,0,-1);
if(strpos($url_substr,'?') === false){
$redirect_url = $url_substr.'?code='.$result['code'];
} else {
$redirect_url = $url_substr.'&code='.$result['code'];
}
redirect($redirect_url);
}
}
Model部分
//餐饮圈用户登录
public function getCode($state = 'STATE',$password = '') {
if ($_REQUEST['code']) {
$code = $_REQUEST['code'];
$lexer = $_REQUEST['state'];
$user_info_json = https_request("https://api.weixin.qq.com/sns/oauth2/access_token?appid=".C('WX_APPID')."&secret=".C('WX_APPSECRET')."&code=".$code."&grant_type=authorization_code");
$user_info = json_decode($user_info_json,true);
$user_info_json11 = https_request("https://api.weixin.qq.com/sns/userinfo?access_token=".$user_info['access_token']."&openid=".$user_info['openid']."&lang=zh_CN ");
$data = json_decode($user_info_json11,true);
//是否已经关注
$is_subscribe = $this->checkSubscribe($data['openid']);
$wx_data['is_subscribe'] = $is_subscribe==1?$is_subscribe:0;
//查询wx_users是否有记录,记录在用户表中
$exist = $this->getByUnionID($data['unionid']);
S($code,$data,3000);
if(empty($exist)){
$wx_data['sex'] = $data['sex'];
$wx_data['city'] = $data['city'];
$wx_data['province'] = $data['province'];
$wx_data['country'] = $data['country'];
$wx_data['unionid'] = $data['unionid'];
$wx_data['openid'] = $data['openid'];
$wx_data['nickname'] = $data['nickname'];
$wx_data['headimgurl'] = $data['headimgurl'];
//添加用户信息
$this->addWeixin($wx_data);
} else {
//用户存在,修改用户
$wx_data['id'] = $exist['id'];
if(!empty($exist['nickname']) && !empty($exist['headimgurl']) ) {
if(strpos($exist['headimgurl'], 'http://') !== 0 || strpos($exist['headimgurl'], 'https://') !== 0){
unset($data['nickname']);
unset($data['headimgurl']);
}
}
//更新用户信息
$this->upObj($wx_data);
}
$return['code'] = $code;
$return['lexer'] = base_decodes($lexer);
return $return;
} else {
if($password != C('WX_PWD')){
exit("Password error");
}
$back_url = "https://b2b.taoxiansheng.com/phone/Api/get_user_code";
header("Location: https://open.weixin.qq.com/connect/oauth2/authorize?appid=".C('WX_APPID')."&redirect_uri="
. urlencode($back_url)."&response_type=code&scope=snsapi_userinfo&state=".base_encodes($state)."#wechat_redirect" );
exit;
}
}
通过这样的操作, 登录B公众号项目的时候先使用A授权, 因为推广的是A公众号,所以需要给用户发送额模版消息应该使用A公众号的openid等信息, 而其他的业务操作需要在B公众号进行, 因此在项目中需要B公众号信息的地方再用B公众号授权一次, 这种做法实属无奈之举, 但是业务就这样没办法...
A项目的用户表记录微信信息后, 通过业务上的相关操作,将用户信息存入B项目的用户表中,此时必须要存用户的unionid, 这是不同工种号关联用户的唯一纽带
/**
* 用户登录
* User/login_option
* @param user_name 手机号
* @param password 密码
* @param code 验证码
* 2018.01.17
* BY HF
*/
public function login_option(){
config('default_return_type','json');
$param=$this->request->param();
$result = $this->validate($param,'User.login');
if(true !== $result){
// 验证失败 输出错误信息
return ['code'=>400,'message'=>$result];
}
$code_info=Db::name('code_info')->where(['mobile'=>$param['user_name']])->order('code_info_id desc')->find();
if($code_info){
if(time() - $code_info['time'] > 60 * 20){
Db::name('code_info')->delete($code_info['code_info_id']);
return ['code'=>400,'message'=>'验证码已失效,请重新发送'];
}else {
if ($code_info['code'] != $param['code']) {
return ['code' => 400, 'message' => '验证码输入错误'];
}
}
}else{
return ['code'=>400,'message'=>'未发送验证码'];
}
unset($param['code']);
$info=Db::name('users')->where(['user_name'=>$param['user_name']])->find();
if($info){ //用户存在,登录
$token = authcode($info['user_id'],"ENCODE", config('api.api_key'));
$data=[
'token'=>$token,
'user_id'=>$info['user_id'],
'nickname'=>$info['nickname'],
'user_name'=>$info['user_name']
];
$userModel = new Users();
$userModel->where(['user_name'=>$param['user_name']])->data(['last_time'=>date('Y-m-d H:i:s'),'last_ip'=>request()->ip()])->update();
$return=array_merge(['code'=>200,'message'=>'登录成功'],$data);
return $return;
}else{
//param参数应该包含unionid
$userModel = new Users();
$param['credit_line'] = 5;
$param['reg_step'] = 2;
//是客户经理推荐的填写客户经理的信息
if(isset($param['referrer_id']) && !empty($param['referrer_id'])&& $param['referrer_id']!='null'){
//客户经理信息
$salesman = $userModel->getSalesman($param['referrer_id']);
$param['referrer_name'] = $salesman['name'];
} else {
$param['referrer_name'] = 0;
$param['referrer_id'] = 0;
}
Log::log('login:date:'.date('Y-m-d H:i:s',time()).'&login_data='.var_export($param, true));
//使用集采平台授权授权注册,不记录集采平台的openid
unset($param['openid']);
$userModel->data($param)->save();
$id = $userModel->user_id;
//记录积分
Db::name('credit')->insert(['user_id'=>$id,'item'=>'user_name','value'=>5,'create_time'=>date('Y-m-d H:i:s')]);
$token = authcode($id,"ENCODE", config('api.api_key'));
$data=[
'token'=>$token,
'user_id'=>$id,
];
$return = array_merge(['code'=>200,'message'=>'登录成功'],$data);
return $return;
}
}
以上是我项目中给B项目技术数据的方式
3. 项目操作中需要B公众号授权的
Controller
//微信浏览器,用户自动登录,并重新定向 附带code参数
// back_url 经过urlencode的回跳地址
public function get_user_code(){
$back_url = input("redirect_uri","","urldecode");
$password = input("password","","trim");
$WxUsersModel = model('Wechat');
$result = $WxUsersModel->getUserInfo($back_url,$password);
if(isset($result['code']) && isset($result['lexer'])){
$url = $result['lexer'];
$url_replace=preg_replace('/(.*)(?|&)code=[^&]+?(&)(.*)/i','$1$2$4',$url.'&');
$url_substr=substr($url_replace,0,-1);
if(strpos($url_substr,'?') === false){
$redirect_url = $url_substr.'?code='.$result['code'];
} else {
$redirect_url = $url_substr.'&code='.$result['code'];
}
return redirect($redirect_url);
}
}
Model
//获取用户详细信息
//$lexer 原样返回的数据
public function getUserInfo($lexer = 'STATE',$password = "") {
if (isset($_REQUEST['code'])) {
$code = input('code','','trim');
$state = input('state','','trim');
$user_access_token_json = https_request("https://api.weixin.qq.com/sns/oauth2/access_token?appid=".$this->appid."&secret=".$this->appsecret."&code=".$code."&grant_type=authorization_code");
$user_access_token = json_decode($user_access_token_json,true);
$user_info_json = https_request("https://api.weixin.qq.com/sns/userinfo?access_token=".$user_access_token['access_token']."&openid=".$user_access_token['openid']."&lang=zh_CN ");
$resuult = json_decode($user_info_json,true);
cache($code,$resuult,300);
//更新B公众号项目用户表的openid
model('Users')->save(['openid' => $resuult['openid']], ['unionid' => $resuult['unionid']]);
$return['lexer'] = $state == 'STATE' ? "" : base_decodes($state);
$return['code'] = $code;
return $return;
} else {
if($password != $this->password){
exit("请求密码错误");
}
$back_url = get_url();
header("Location: https://open.weixin.qq.com/connect/oauth2/authorize?appid=".$this->appid."&redirect_uri="
. urlencode($back_url)."&response_type=code&scope=snsapi_userinfo&state=".base_encodes($lexer)."#wechat_redirect" );
// header("Location: https://open.weixin.qq.com/connect/oauth2/authorize?appid=".$this->appid."&redirect_uri="
// . urlencode($back_url)."&response_type=code&scope=snsapi_userinfo&state=STATE#wechat_redirect" );
exit;
}
}
将两边的公众号openid和unionid都记录到数据库,以后就好操作了, 为了避免用户每次操作的时候都感觉不停地微信授权,降低体验感, 应该做一定的判断, B公众号的额openid获取到一次之后就不用在授权了