wx.login()
获取临时登录凭证code ,并回传到开发者服务器。auth.code2Session
接口,换取用户唯一标识OpenID
和会话密钥session_key
。注意:
会话密钥 session_key
是对用户数据进行加密签名的密钥。为了应用自身的数据安全,开发者服务器不应该把会话密钥下发到小程序,也不应该对外提供这个密钥。
临时登录凭证 code
只能使用一次。
1、获取登录凭证code
login() {
wx.login({
success(res) {
if (res.code) {
//发起网络请求
wx.request({
url: 'http://127.0.0.1:18080/wx/login',
method: 'POST',
header: {'content-type': 'application/x-www-form-urlencoded'},
data: {
code: res.code
},
success(res) {
if (res.data.status == 200) {
let ticket = res.data.ticket;
// 保存自定义登录态至客户端
wx.setStorage({
key: 'LOGIN',
data: ticket
})
} else {
// 登录失败
wx.removeStorage({
key: 'LOGIN'
})
}
}
})
} else {
console.log('登录失败!' + res.errMsg)
}
}
})
}
2、调用 auth.code2Session
接口校验登录凭证
GET https://api.weixin.qq.com/sns/jscode2session?appid=APPID&secret=SECRET&js_code=JSCODE&grant_type=authorization_code
填入对应的小程序ID、密钥、和刚刚获得的凭证code,得到响应:
{"session_key":"5tF5KuDigyB6e4m7FigHvw==",
"openid":"orWy35UBNFZyReiUYVZvtPrqht-0"}
该信息不能直接存储至客户端,需在服务端做保存(这里选择存储至redis中)。
@RestController
@RequestMapping("/wx")
public class WeixinController {
@Autowired
private RestTemplate restTemplate;
@Autowired
private RedisTemplate<String, String> redisTemplate;
public static final String APPID = "your_appid";
public static final String SECRET = "your_secret_key";
@PostMapping("/login")
public Map<String, Object> wxLogin(@RequestParam("code") String code) {
Map<String, Object> result = new HashMap<>();
result.put("status", 200);
String url = "https://api.weixin.qq.com/sns/jscode2session?appid=" + APPID +
"&secret=" + SECRET + "&js_code=" + code + "&grant_type=authorization_code";
String jsonResult = restTemplate.getForObject(url, String.class);
if (StringUtils.contains(jsonResult, "errcode")) {
// 登陆凭证校验错误 code been used
result.put("status", 5000);
result.put("msg", "登陆失败");
return result;
}
// 校验通过
//
String md5Key = DigestUtils.md5Hex(jsonResult + "HAOKE_WX_LOGIN");
String redisKey = "WX_LOGIN_" + md5Key;
redisTemplate.opsForValue().set(redisKey, jsonResult, Duration.ofDays(7));
result.put("ticket", "HAOKE_" + md5Key);
return result;
}
}
错误响应:
code只能被使用一次
{"errcode":40163,"errmsg":"code been used, hints: [ req_id: tCpcZfyFe-myWCca ]"}
3、保存自定义登录态至客户端
通过wx.setStorage
,具体代码在前面贴了。
4、校验是否登录
checkSession() {
const _this = this;
wx.checkSession({
success() {
wx.showToast({
title: '已登录',
icon: 'success',
duration: 2000
})
},
fail() {
wx.showToast({
title: '登录失效',
icon: 'none',
duration: 2000
})
_this.login() // 重新登录
}
})
},
6、发起业务请求时,携带客户端中的自定义登录态,去redis查询到对应的session_key和openid。