1.登录流程图:三大服务器(小程序,开发者服务器,微信官方服务器)

2.微信小程序登录逻辑:
- 步骤一:在小程序客户端获取当前登录微信用忽的凭证(code)
使用 wx.login() 方法得到一个临时登录凭证,我们可以在小程序的App构造代码中发起登录凭证请求,也可以在其他page页面调用 - 步骤二:将登录凭证发送到开发者服务端,开发者服务端获取code发送到微信服务器获取用户唯一标识(openId)和会话秘钥(session_key),代码实现如下:
wx.login({
success:function(response){
var code = response.code;
if(code){
console.log("用户登录凭证:"+code);
}
wx.request({
url:'开发者服务器api接口',
data:{code:code}
})
}
})
开发者服务器代码:
static String grantType = "authorization_code";
static String wxUrl = "https://api.weixin.qq.com/sns/jscode2session?";
static String appId = "";
static String appsecret = "";
//微信小程序登录
@GetMapping("/code")
public String getLoginCode(@RequestParam("code")String code){
System.out.println(code);
CloseableHttpClient httpclient = HttpClients.createDefault();
String resultString = "";
CloseableHttpResponse response = null;
String session_key = "";
String openid = "";
String url = wxUrl + "appid="+appId+"&"+"secret="+appsecret+"&"+"js_code="+code+"&"+"grant_type="+grantType;
try {
// 创建uri
URIBuilder builder = new URIBuilder(url);
URI uri = builder.build();
// 创建http GET请求
HttpGet httpGet = new HttpGet(uri);
// 执行请求
response = httpclient.execute(httpGet);
// 判断返回状态是否为200
if (response.getStatusLine().getStatusCode() == 200) {
resultString = EntityUtils.toString(response.getEntity(), "UTF-8");
}
} catch (Exception e) {
e.printStackTrace();
}
// 解析json
JSONObject jsonObject = (JSONObject) JSONObject.parse(resultString);
session_key = jsonObject.get("session_key")+"";
openid = jsonObject.get("openid")+"";
System.out.println("session_key=="+session_key);
System.out.println("openid=="+openid);
return resultString;
这段后台代码成功执行事务话,就可以得到openid和session_key,这个信息就是当前微信账户在微信服务器那边的登录态
ps: 为了安全方面的原因,不要直接使用这些信息作为小程序的用户标识和session标识回传到小程序客户端中去,我们应该在服务器端做一层自己的session,将这个微信账号登录态生成一个session_id并维护在我们自己的session机制中,然后把这个sessoin_id发送到小程序客户端作为session标识来使用。
我们一般采用键值对存储工具,比如:redis ,将每个session生成一个唯一的字符串作为键,然后可以将session_key和openid作为值,存入redis中,存入的时候设置超时时间(session过期时间)

ps: 3rd_session就是后台服务器生成的随机数。后台服务器可以调用head -n 80 /dev/urandom | tr -dc A-Za-z0-9 | head -c 168这样的shell 命令获取168位的随机字符串。
步骤三: 在客户端保存session_id (s3rd_session)
开发web项目时,我们在客户端通常将sessiosn_id存放在cookie中,但是小程序没有cookie机制,所以不能采用cookie,但是小程序有本地的storage,所以我们使用storage来保存sessionid,以供后续后台api调用所使用。在之后,调用那些需要登录后才有权限的访问的后台服务时,你可以将保存在storage中的sessionid取出并携带在请求中(可以放在header中携带,也可以放在querystring中,或是放在body中,根据你自己的需要来使用),传递到后台服务,**后台代码中获取到该sessionid后,从redis中查找是否有该sessionid存在,存在的话,即确认该session是有效的,继续后续的代码执行,否则进行错误处理。 **(这里的后台服务是指在自己服务器去调用的微信后台服务,也就是先请求自己服务器的服务,然后根据sessionid获取到openid和session_key后再调用微信服务器的服务,成功后由自己服务器返回给微信小程序。)
会话密钥 session_key 有效性
开发者如果遇到因为 session_key 不正确而校验签名失败或解密失败,请关注下面几个与 session_key 有关的注意事项。
1,wx.login 调用时,用户的 session_key 可能会被更新而致使旧 session_key 失效(刷新机制存在最短周期,如果同一个用户短时间内多次调用 wx.login,并非每次调用都导致 session_key 刷新)。开发者应该在明确需要重新登录时才调用 wx.login,及时通过 auth.code2Session 接口更新服务器存储的 session_key。
2,微信不会把 session_key 的有效期告知开发者。我们会根据用户使用小程序的行为对 session_key 进行续期。用户越频繁使用小程序,session_key 有效期越长。
3,开发者在 session_key 失效时,可以通过重新执行登录流程获取有效的 session_key。使用接口 wx.checkSession可以校验 session_key 是否有效,从而避免小程序反复执行登录流程。
4,当开发者在实现自定义登录态时,可以考虑以 session_key 有效期作为自身登录态有效期,也可以实现自定义的时效性策略。
转载:https://blog.youkuaiyun.com/weixin_40333655/article/details/90485153
1万+

被折叠的 条评论
为什么被折叠?



