前端判断用户没登录---携带回调地址重定向到后端授权服务器---后端发起授权---微信授权通过---注册用户并生成token ---重定向到前端提交的地址并携带token---前端获取token ---携带token请求其他接口
当多个公众号用另外一个公众号进行支付时,可以用静默授权获取发起支付公众号的openID,进行关联,这样就不要开发平台获取unicoid关联账号
public function __construct(Request $request)
{
global $_W;
$this->wechat_model = new Wechats();
$this->member_model = new Members();
$configModel = new Setting();
$uniacid = $request->param('uniacid',0);
$wechatInfo = $this->wechat_model->getInfoById($uniacid);
if (!$wechatInfo && $request->action() == 'login')//公众号不存在
{
$res['status']="102";
$res['msg']='站点错误';
$res['data']="";
sendResponse($res,400,'Bad Request');
}
$_W['uniacid'] = $uniacid;
$_W['wechatInfo'] = $wechatInfo;
$this->config = [
'app_id' => $wechatInfo['key'],
'secret' => $wechatInfo['secret'],
'token' => $wechatInfo['token'],
'response_type' => 'array',
'log' => [
'level' => 'debug',
'file' => __DIR__.'/wechat.log',
],
'oauth' => [
'scopes' => ['snsapi_userinfo'],
'callback' => $_SERVER['SCRIPT_NAME'].'/index/login/oauth_callback?uniacid='.$uniacid.'¶m='.urlencode(http_build_query($request->param())),
],
//平台公众号配置
$this->base_config = [
'app_id' => $configModel->get('ADMIN_APP_ID')->conf_value,
'secret' => $configModel->get('ADMIN_SECRET')->conf_value,
'response_type' => 'array',
'log' => [
'level' => 'debug',
'file' => __DIR__.'/wechat.log',
],
'oauth' => [
'scopes' => ['snsapi_base'],
'callback' => $_SERVER['SCRIPT_NAME'].'/index/login/oauth_callback_base?param='.urlencode(http_build_query($request->param())),
],
];
}
];
public function Login(Request $request)
{
global $_W;
$call_back_url = $request->param('url','');
$popularize_id = $request->param('popularize_id',0);
if (!$call_back_url)
return json(['data'=>'','error'=>1,'message'=>'回调地址不能为空']);
$app = Factory::officialAccount($this->config);
$oauth=$app->oauth;
return $oauth->redirect()->send();
}
scopes 有snsapi_userinfo 获取详细信息 和snsapi_base 静默授权值能取到openID 两种方式
urlencode(http_build_query($request->param() //将数组参数换为url形式(a=1&b=2)然后url编码
public function oauth_callback(Request $request){
global $_W;
$app = Factory::officialAccount($this->config);
$oauth = $app->oauth;
$user = $oauth->user();
$info = $user->getOriginal();
$user_detail = $app->user->get($info['openid']);
$userInfo = $this->member_model->getInfoByWhere(['openid' =>$info['openid'],'uniacid' => $_W['uniacid']]);
$data = array(
'nickname' => $info['nickname'],
'gender' => $info['sex'],
'avatar' => $info['headimgurl'],
'province' => $user_detail['province'] ?? '',
'city' => $user_detail['city'] ?? '',
'follow' => $user_detail['subscribe'] ?? 0,
'follow_time' => $user_detail['subscribe_time'] ?? 0,
);
if (empty($userInfo))//新增
{
$data['openid'] = $info['openid'];
$data['uniacid'] = $_W['uniacid'];
$data['auid'] = $_W['wechatInfo']['auid'];
}else
{
$data['id'] = $user['id'];//跟新
}
$this->member_model->login($data);
$jwtToken = new Token();
$tokenData = array(
'openid' => $user->getId(),
'uniacid' => $_W['uniacid'],
);
$token = $jwtToken->createToken($tokenData)['token'];
parse_str(urldecode($request->param('param')),$param);//url解码并转成数组
if (empty($userInfo['base_openid']))//获取平台公众号openid
{
$userInfo = $this->member_model->getInfoByWhere(['openid' =>$info['openid'],'uniacid' => $_W['uniacid']]);
$param['token'] = $token;
$param['user_id'] = $userInfo['id'];
$this->redirect('index/login/getBaseOpenid',$param);
}else{
if (strpos($param['url'],'?'))
$this->redirect($param['url']."&token=$token");
else
$this->redirect($param['url']."?token=$token");
}
}
此处获取用户详细信息之后写入数据库,生成一个token用于,后将回调地址解码带上token,重定向到该地址
形如:http://vvv.com/a.html?a=1&token=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9
然后前端截取token,以后请求其他接口时写入header头的AUTHORIZATION,用于验证
token 生成与验证见链接
https://blog.csdn.net/flysnownet/article/details/90260826
BASE 控制器
class Base extends Controller
{
public function __construct()
{
global $_W;
Hook::listen('response_send');//跨域
if (empty($_SERVER['HTTP_AUTHORIZATION']))
{
$res['status']="201";
$res['msg']="no token";
$res['data']="";//返回的数据
sendResponse($res,401,'Unauthorized');
}
$token = $_SERVER['HTTP_AUTHORIZATION'];
$jwtToken = new Token();
$checkToken = $jwtToken->checkToken($token);
$data = (array)$checkToken['data']['data'];
$openid = $data['openid'] ?? 0 ;
$uniacid = $data['uniacid'] ?? 0 ;
if (0 == ($openid && $uniacid))
{
$res['status']="202";
$res['msg']="bad token";
$res['data']="";
sendResponse($res,401,'Unauthorized');
}
$wechatModel = new Wechats();
$memberModel = new Members();
$wechatInfo = $wechatModel->getInfoById($uniacid);//公众号信息
$_W['user'] = $memberModel->getInfoByOpenidAndUniacid($openid,$uniacid);//用户信息
$_W['wechat_info'] = $wechatInfo;
}
}