基于spring boot实现微信小程序登录
wx.login
调用接口获取登录凭证(code)。通过凭证进而换取用户登录态信息,包括用户在当前小程序的唯一标识(openid)、微信开放平台帐号下的唯一标识(unionid,若当前小程序已绑定到微信开放平台帐号)及本次登录的会话密钥(session_key)等。用户数据的加解密通讯需要依赖会话密钥完成。
code,用户登录凭证(有效期五分钟)。开发者需要在开发者服务器后台调用 auth.code2Session,使用 code 换取 openid、unionid、session_key 等信息。
openid:指的微信用户在微信的某个应用中的唯一标识。
unionid:指的微信用户的唯一标识。(相当于微信用户ID)
微信某个应用:指的是 公众号、小程序、开放平台等。
若要开发多个微信应用,应当获取微信用户的唯一标识 unionid。
在app.js的onluanch方法里面加入如下代码
// 登录
wx.login({
success: res => {
var parma={};
parma.code=res.code;
BSAPI.userlogin(parma).then(loginres=>{
if(loginres.success){
wx.setStorageSync('user', loginres.xcxuser);
wx.setStorageSync('token', loginres.token);
//this.getInfo();
if (_this.loginCallback){
_this.loginCallback(loginres.token);
}
}
});
}
})
在页面的onshow方法中等待登录逻辑执行完毕再加载页面内容。
onShow: function () {
var token=wx.getStorageSync('token');
// console.log("onLoad:",token)
if(!token){
app.loginCallback=(token_=>{
if(token_){
wx.setStorageSync('token', token_);
//业务代码
}
})
}else{
//业务代码
}
},
统一请求封装
const API_BASE_URL = 'https://域名' // 主域名
const request = (url, method, data) => {
let _url = API_BASE_URL + url
return new Promise((resolve, reject) => {
wx.request({
url: _url,
method: method,
data: data,
header: {
'content-type': 'application/x-www-form-urlencoded',
// 'openid': wx.getStorageSync('user').openid,
// 'unionid': wx.getStorageSync('user').unionid,
'apitoken':wx.getStorageSync('token')
},
success(r) {
if(r.statusCode == 200){
resolve(r.data)
}
else if(r.statusCode == 401){
wx.navigateTo({
url: '/pages/user/userauth',
})
}
else{
wx.showToast({
title: '未知错误',
icon:"none"
})
}
},
fail(error) {
reject(error)
},
complete(aaa) {
// 加载完成
}
})
})
}
/**
* 小程序的promise没有finally方法,自己扩展下
*/
Promise.prototype.finally = function (callback) {
var Promise = this.constructor;
return this.then(
function (value) {
Promise.resolve(callback()).then(
function () {
return value;
}
);
},
function (reason) {
Promise.resolve(callback()).then(
function () {
throw reason;
}
);
}
);
}
module.exports = {
API_BASE_URL,
request,
userlogin: data => request('/xcxlogin', 'post', data),
updateuserinfo: data => request('/updateuserinfo', 'post', data),
//查询聊天会话
querychatgroup: data => request('/querychatgroup', 'post', data),
querychatmessage: data => request('/querychatmessage', 'post', data),
}
后端接口
@ApiOperation(value = "小程序登录", httpMethod = "POST")
@RequestMapping("/xcxlogin")
public R xcxlogin(HttpServletRequest request, TbSysEmploy entry) {
Assert.notEmpty(entry.getCode(),ResponseEnum.BAD_PARAMETER);
HashMap<String,Object> ret=new HashMap<String,Object>();
WeChatUserVo weChatUserVo= weChatService.queryEmpWeChatUserBy(entry.getCode());
weChatUserVo.setLoginType(EmpLoginTypeEnu.TYPE_XCX.getCode());
weChatUserVo=tbSysEmployService.loadOrRegister(weChatUserVo);
ret.put("user",weChatUserVo);
TbApiToken temp=new TbApiToken();
temp.setUnionid(weChatUserVo.getUnionId());
temp.setUserid(weChatUserVo.getId());
temp.setUsername(weChatUserVo.getRealname());
TbApiToken tbApiToken=tbApiTokenService.createApiToken(temp);
ret.put("token",tbApiToken.getApitoken());
return R.ok().data(ret);
}
@Override
public WeChatUserVo queryEmpWeChatUserBy(String code) {
WeChatUserVo weChatUserVo=null;
try{
String tempurl = weChatProperties.getAccessTokenUrl().replaceAll("GRANT_TYPE", weChatProperties.getEmp().getGrantType()).replaceAll("APPID", weChatProperties.getEmp().getAppId()).replaceAll("SECRET", weChatProperties.getEmp().getSecret()).replaceAll("CODE", code);
HttpsClient http = new HttpsClient();
// 调用获取access_token接口
Response res = http.get(tempurl);
// 根据请求结果判定,是否验证成功
JSONObject jsonObj = res.asJSONObject();
if (jsonObj != null) {
Object errcode = jsonObj.get("errcode");
if (errcode != null) {
// 返回异常信息
throw new Exception(errcode.toString());
}
String unionid = jsonObj.containsKey("unionid") ? (String) jsonObj.get("unionid") : "";
String openid = jsonObj.containsKey("openid") ? (String) jsonObj.get("openid") : "";
weChatUserVo=new WeChatUserVo(openid,unionid);
}
}catch (Exception e){
e.printStackTrace();
}
return weChatUserVo;
}