【开源微信】微信登入公众号、小程序
2023/7/17 9:00:00 【次浏览】 本站
1、概述
基于用户的微信信息进行登入是常用用户登入方法,支持在微信公众号、微信小程序等不同终端进行微信登入。设计统一微信登入框架,实现一套PHP前后端分离开源框架奇辰Open-API。
2、登入框架
不管是微信公众号或是微信小程序,微信登入分为两个步骤:
获取登入code:在微信公众号平台,通过1.1.1步骤跳转到微信公众号平台的授权域名,在回调的微信公众号官方后台指定域名可以在回调url参数里面获取code,如图1.1.2步骤;在微信小程序平台可以直接在小程序端调用wx.login函数获取code参数,如图1.2步骤。
通过code进行登入授权:利用获得的code可以调用微信基础API、SDK获取用户微信信息,主要是用户微信针对相应公众号或小程序的唯一openid。在开源框架奇辰Open-API里已封装好第三方微信基础API、SDK的调用回调工作。
3、开 源实现
3.1微信公众平台登入
前端网页授权
export function authLogin(mode, callback_page) {
mpConf().then(res => {
var appid = res.data.appid
let href = window.location.href
var url = new URL(href)
var local = encodeURIComponent(url.origin + callback_page); // 当前H5页面的url
var wxUrl =
'https://open.weixin.qq.com/connect/oauth2/authorize?appid=' +
appid +
'&redirect_uri=' +
local +
'&response_type=code' +
'&scope=snsapi_' + (mode === 'userinfo' ? 'userinfo' : 'base') +
'&state=STATE#wechat_redirect';
window.location.href = wxUrl;
}).catch(err => {
console.log("获取code失败")
})
}
callback_page设置授权回调页面url,获取授权成功回调url携带参数code。
微信公众号请求后端登入
export function login() {
return new Promise((resolve, reject) => {
const url_params = getUrlCode()
const openid = url_params.openid
if (openid !== '' && openid != null && openid != undefined) {
request('/auth/mp/openid', {
openid: openid
}, 'POST').then(res => {
//成功回调
if (res.errorCode == 200) {
uni.setStorageSync('token', res.data.token);
resolve(res);
} else {
reject('non login!');
}
}).catch(err => {
//请求失败
console.log("openid 登入失败!")
reject(err)
})
} else {
const code = url_params.code;
if (code !== null && code !== '' && code !== undefined) {
request('/auth/mp/code', {
code: code
}, 'POST').then(res => {
if (res.errorCode == 200) {
uni.showToast({
title: '微信登入成功',
icon: 'none'
})
uni.setStorageSync('token', res.data.token);
resolve(res);
} else {
console.log(res)
reject('non login!');
}
}).catch(err => {
console.log("login error: code2session 错误!")
reject('code auth error')
})
} else {
reject('no code')
}
}
})
}
第24行调用后端auth/mp/code接口进行登入授权,如下:
后端微信公众号授权登入
public function code(Request $request)
{
$conf = ConfMpModel::first();
$http = new GuzzleHttp\Client;
$params = [
'appid' => $conf->appid,
'secret' => $conf->secret,
'code' => $request->code,
'grant_type' => 'authorization_code'
];
$response = $http->get('https://api.weixin.qq.com/sns/oauth2/access_token', [
'query' => $params
]);
$result = json_decode($response->getBody(), true);
if (array_key_exists('errcode', $result) && $result['errcode'] != 0) {
$res = ResultTool::fail();
$res['errorCode'] = $result['errcode'];
$res['errorMsg'] = $result['errmsg'];
return $res;
}
if (array_key_exists('openid', $result) && $result['openid'] != '') {
$fans = FansModel::where('openid', '=', $result['openid'])->where('platform', '=', 'mp')->first();
if (!is_null($fans)) {
if (!($fans->uid > 0)) {
$uid = $this->user_service->registerForFans($fans->fid);
$fans->uid = $uid;
$fans->save();
}
} else {
$fid = $this->fans_service->registerOpenid('mp', $result['openid']);
$fans = FansModel::where('openid', '=', $result['openid'])->first();
$uid = $this->user_service->registerForFans($fid);
$fans->uid = $uid;
$fans->save();
}
$user = UserModel::where('uid', '=', $fans->uid)->first();
$token = Auth::login($user);
$res = ResultTool::success();
$res['data']['token'] = $token;
return $res;
}
$res = ResultTool::fail();
$res['errorMsg'] = '微信公众号用户登入失败!';
return $res;
}
3.2微信小程序登入
微信小程序端获取code,并请求后端授权登入
export function login() {
try {
return new Promise((resolve, reject) => {
uni.login({
provider: 'weixin',
success: (loginRes) => {
let data = {
code: loginRes.code
}
request(
'auth/miniapp/login', data,
'POST'
)
.then((res) => {
//成功回调
if (res.errorCode == 200) {
uni.setStorageSync('token', res.data.token);
userOfMiniapp().then(res => {
uni.setStorageSync('user_info', res.data)
})
resolve(res.data.token);
} else {
reject(res)
}
})
.catch((err) => {
//请求失败
reject(err);
});
},
});
});
} catch (e) {
// error
}
}
在第4行调用前端函数获取code,在第10行请求后端进行授权登入。
后端微信小程序登入
public function login(Request $request)
{
$conf = ConfModel::first();
$http = new GuzzleHttp\Client;
$params = [
'appid' => $conf->miniapp_appid,
'secret' => $conf->miniapp_secret,
'js_code' => $request->code,
'grant_type' => 'authorization_code'
];
$response = $http->get('https://api.weixin.qq.com/sns/jscode2session', [
'query' => $params
]);
$result = json_decode($response->getBody(), true);
if (array_key_exists('errcode', $result) && $result['errcode'] != 0) {
$res = ResultTool::fail();
$res['errorCode'] = $result['errcode'];
$res['errorMsg'] = $result['errmsg'];
return $res;
}
if (array_key_exists('openid', $result) && $result['openid'] != '') {
$fans = FansModel::where('openid', '=', $result['openid'])->where('platform', '=', 'miniapp')->first();
if (!is_null($fans)) {
if (!($fans->uid > 0)) {
$uid = $this->user_service->registerForFans($fans->fid);
$fans->uid = $uid;
$fans->save();
}
} else {
$fid = $this->fans_service->registerOpenid('miniapp', $result['openid']);
$fans = FansModel::where('openid', '=', $result['openid'])->first();
$uid = $this->user_service->registerForFans($fid);
$fans->uid = $uid;
$fans->save();
}
$user = UserModel::where('uid', '=', $fans->uid)->first();
$token = Auth::login($user);
$res = ResultTool::success();
$res['data']['token'] = $token;
return $res;
}
$res = ResultTool::fail();
$res['errorMsg'] = '小程序用户登入失败!';
return $res;
}
手机扫码查看当前文章: