概述
- 授权登录流程
- 具体实现方法
微信小程序登录流程
微信小程序登录时序图
第一步:小程序通过wx.login()获取code。
第二步:小程序通过wx.request()发送code到开发者服务器。
第三步:开发者服务器接收小程序发送的code,并携带appid、appsecret(这两个需要到微信小程序后台查看)、code发送到微信服务器。
第四步:微信服务器接收开发者服务器发送的appid、appsecret、code进行校验。校验通过后向开发者服务器发送session_key、openid。
第五步:开发者服务器自己生成一个skey(自定义登录状态)与openid、session_key进行关联,并存到数据库中(mysql、redis等)。
第六步:开发者服务器返回生成skey(自定义登录状态)到小程序。
第七步:小程序存储skey(自定义登录状态)到本地。
第八步:小程序通过wx.request()发起业务请求到开发者服务器,同时携带skey(自定义登录状态)。
第九步:开发者服务器接收小程序发送的skey(自定义登录状态),查询skey在数据库中是否有对应的openid、session_key。
第十步:开发者服务器返回业务数据到小程序。
具体实现
第一步:小程序通过wx.login()获取code。
在前端小程序中,小程序加载时在app.js 中会判断用户是否授权,授权了直接获取用户的授权信息,未授权跳转到授权页面进行授权
授权页面loginAuthorize/Loginwechat
调用wx.login()方法,从微信后台服务器中获取code信息
第二步:小程序通过wx.request()发送code到开发者服务器。
使用wx.request()方法将code等信息发送到后台服务器,服务器接收
wx.login({
success:function(login_res){
console.log("登录回调信息:",login_res)
// 1.使用微信login方法获取code ,将其上传到后台
// 2.后台获取code,和appid secret后 上传到微信后台获取session
// rawdata 里是用户的非敏感信息
var code =login_res.code;
var rowdata = info_res.detail.rawData;//用户非敏感信息
var encryptedData = info_res.detail.encryptedData;//用户敏感信息
var signature = info_res.detail.signature;//用户签名
var iv =
info_res.detail.iv;//解密算法的向量
// 发起网络请求,将code传至后台,获取session_key,secret
wx.request({
url:'http://localhost:8080/wxLogin',
method:"Post",
header:{'content-type':'application/x-www-form-urlencoded'},
data:{
"code": code,
"rawdata": rowdata,
"encryptedData":encryptedData,
"signature":signature,
"iv":iv
},
success:function(result){
console.log(result)
// 登录成功跳转index页面
wx.switchTab({
url: '/pages/index/index'
});
}
})
}
})
第三步:开发者服务器接收小程序发送的code,并携带appid、appsecret(这两个需要到微信小程序后台查看)、code发送到微信服务器。
第四步:微信服务器接收开发者服务器发送的appid、appsecret、code进行校验。校验通过后向开发者服务器发送session_key、openid。
后台服务器获取到code等信息之后,加入自己的appid 和APPsecret,将其发送到微信后台服务器,来获取openid、session_key
在实现的过程中controller中
//调用WxUtils里的方法获取session和openid
// 返回值是一个json对象{"openid":"ogRYf5Zhezc8qASoLebu92fwHLu4","session_key":"IZG5LOgrri5FRFWQ+JRKZQ=="}
JSONObject SessionKeyOpenId = WxUtils.getSessionKeyOrOpenId(code);
在工具类wxutils中,主要用于将要传的数据封装成一个map,在使用HttpClientUtil中的doget方法,将其传到微信后台服务器中
String url = "https://api.weixin.qq.com/sns/jscode2session";
Map<String,String> param = new HashMap<>();
param.put("appid","11111111");
param.put("secret","AAAAAAAAAAAAAAAAAAAAAAAAAA");
param.put("js_code", code);
param.put("grant_type","authorization_code");
String wxResult = HttpClientUtil.doGet(url,param);
System.out.println(wxResult);
JSONObject jsonObjectResult = JSON.parseObject(wxResult);
return jsonObjectResult;
获取到sessionkey和openid
JSONObject SessionKeyOpenId = WxUtils.getSessionKeyOrOpenId(code);
String open_id = SessionKeyOpenId.getString("openid");
String session_key = SessionKeyOpenId.getString("session_key");
签名校验
校验签名 小程序发送的签名signature与服务器端生成的签名signature2 = sha1(rawData + sessionKey)
// 计算sha1值
String signature2 = DigestUtils.sha1Hex(rawdata + session_key);
// 后台验证的签名和前端传来的签名不符,返回校验失败
if (!signature.equals(signature2))
{
return JSONResult.build(500, "签名校验失败", null);
}
第五步:开发者服务器自己生成一个skey(自定义登录状态)与openid、session_key进行关联,并存到数据库中(mysql、redis等)。
第六步:开发者服务器返回生成skey(自定义登录状态)到小程序。
第七步:小程序存储skey(自定义登录状态)到本地。
对于校验成功的用户,根据其openid在数据库中查找其是否为新用户,若是新用户,直接将其信息插入到数据库表中,若不是则将其更新时间,和自定义的skey更新到数据库表中
wxUser wxuser = wxuserService.getUserByOpenId(open_id);
String skey = UUID.randomUUID().toString();
if (wxuser == null) {
String nick_name = rawDataJson.getString("nickName");
String avatar_url = rawDataJson.getString("avatarUrl");
String gender = rawDataJson.getString("gender");
String city = rawDataJson.getString("city");
String country = rawDataJson.getString("country");
String province = rawDataJson.getString("province");
Date date = new Date();
SimpleDateFormat dateFormat= new SimpleDateFormat("yyyy-MM-dd :hh:mm:ss");
// System.out.println(dateFormat.format(date));
// 将时间转换成一个string类型
// Date nowdate =dateFormat.format(date);
Date create_time = date;
Date last_visit_time =date;
int count = wxuserService.insertNewUser(open_id, skey, create_time, last_visit_time, session_key, city, province, country, avatar_url, gender, nick_name);
System.out.println("成功插入了:"+count+"条数据");
}
else {
// 用户已存在,更新用户的最新登录时间,重新设置会话的skey,修改数据
Date date = new Date();
SimpleDateFormat dateFormat= new SimpleDateFormat("yyyy-MM-dd :hh:mm:ss");
// wxUser.setsetLast_visit_time(new Date());
// user.setLastVisitTime(new Date());
// // 重新设置会话skey
// user.setSkey(skey);
// String last_visit_time =dateFormat.format(date);
Date last_visit_time = date;
int count = wxuserService.updateUserLogin(last_visit_time,skey,open_id);
System.out.println("成功更新了:"+count+"条数据");
System.out.println(last_visit_time);
}
JSONResult result = JSONResult.build(200, null, skey);
return result;
}
第七步:小程序存储skey(自定义登录状态)到本地。
第八步:小程序通过wx.request()发起业务请求到开发者服务器,同时携带skey(自定义登录状态)。
由于openid是一个要从微信后台服务器所获取的用户凭证,不能用于前端和开发服务器之间通信凭证,所以需要生成一个skey作为自定义登录状态的凭证,前端拿到skey之后,若要继续和服务器交互,直接用skey就好,在以后的交互过程中,后台查询条件应该是根据skey查询,而不是openid。(第一次登录时还是要查openid,因为那时没有生成skey)
最后
以上就是优美烧鹅为你收集整理的2020-11-09的全部内容,希望文章能够帮你解决2020-11-09所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复