微信官方文档:小程序-开放接口-登录
openid是用户唯一标识
实现思路:微信小程序第一次登录时会加载请求用户是否同意授权 ,点击同意之后,会返回一个临时登录code码,用code通过我们自己的服务器与微信服务器进行交互,获取OpenId相关信息。
流程:
注册微信小程序、登录后台在设置中获得appId和secret(密钥)
调用wx.login()接口获取登录凭证js_code
调用wx.request()接口把js_code发送到服务器后台
在服务器后台,已知appId、secret、js_code
1、前端js
调用wx.login(OBJECT) 获取登录凭证(code)进而换取用户登录态信息,包括用户的唯一标识(openid) 及本次登录的 会话密钥(session_key)等。用户数据的加解密通讯需要依赖会话密钥完成。
代码实例:
//app.js
App({
onLaunch: function() {
wx.login({
success: function(res) {
if (res.code) {
//发起网络请求
wx.request({
url: 'https://test.com/onLogin',//我们自己的服务器地址(获取openid的接口地址)
data: {
code: res.code
},header: {
'content-type': 'json'
}, success: function (res) {
var openid = res.data.openid //返回openid
console.log('openid为' + openid);
}
})
} else {
console.log('获取用户登录态失败!' + res.errMsg)
}
}
});
}
})
2、java后台
后台请求这个地址获取openid和session_key
https://api.weixin.qq.com/sns/jscode2session?appid=APPID&secret=SECRET&js_code=JSCODE&grant_type=authorization_code
这是一个 HTTPS 接口,开发者服务器使用登录凭证 code 获取 session_key 和 openid。其中 session_key 是对用户数据进行加密签名的密钥。
请求参数:
参数 必填 说明
appid 是 小程序唯一标识
secret 是 小程序的 app secret
js_code 是 登录时获取的 code
grant_type 是 填写为 authorization_code
返回参数:
参数 说明
openid 用户唯一标识
session_key 会话密钥
返回说明:
//正常返回的JSON数据包
{
"openid": "OPENID",
"session_key": "SESSIONKEY"
}
//错误时返回JSON数据包(示例为Code无效)
{
"errcode": 40029,
"errmsg": "invalid code"
}
实例代码:
@Controller
@RequestMapping(value = "/index", produces = "application/json;charset=UTF-8")
public class WxController extends BaseController {
@Autowired
private MinprogramConfig config;
/**
* 获取小程序openid
* @param code 登录临时凭证
* @return map
* @author Created by chenrongkang On 2018/8/20
* */
@RequestMapping(value = "/getXCXOpenId")
@ResponseBody
public Map<String, Object> getXCXOpenId(String code) {
Map<String, Object> map = new HashMap<String, Object>();
if (StringUtils.isEmpty(code)) {
throw new BusinessException("code不存在,请重新进入页面");
}
JSONObject ytzh = (JSONObject) JedisBisUtil.get("ytzhOpenId:code:"+code); //从redis缓存中获取对象
try{
if (ytzh == null||StringUtils.isEmpty(String.valueOf(ytzh.get("openid"))) ||"null".equals(String.valueOf(ytzh.get("openid")))) {
ytzh = WeixinUtil.getXCXOpenId(config.getWx_appid(),config.getWx_appsecret(), code);
if (ytzh == null) {
throw new BusinessException("请重新进入页面");
}
JedisBisUtil.put("ytzhOpenId:code:"+code, ytzh);
JedisBisUtil.expire("ytzhOpenId:code:"+code, 1800);
}
}catch(Exception e) {
if (e instanceof BusinessException) {
throw new BusinessException(((BusinessException) e).getCode(), e.getMessage());
}
ExceptionLogger.error(e);
throw new BusinessException("查询出错");
}
map.put("ytzh", ytzh);
return map;
}
}
WeixinUtil.getXCXOpenId:
/**
* 微信小程序
* 获取openid的方法
* @param appId
* @param appSecret
* @param code
* @return JSONObject对象//含有openid、session_key、unionid的键值对
* @author Created by chenrongkang On 2018/8/20
* */
public static JSONObject getXCXOpenId(String appId, String appSecret, String code) {
JSONObject obj = null;
// 拼接请求地址
String requestUrl = "https://api.weixin.qq.com/sns/jscode2session?appid=APPID&secret=SECRET&js_code=JSCODE&grant_type=authorization_code";
requestUrl = requestUrl.replace("APPID", appId);
requestUrl = requestUrl.replace("SECRET", appSecret);
requestUrl = requestUrl.replace("CODE", code);
try {
String res = HttpUtils.fromUrl(requestUrl); //http模拟发送请求,返回json字符串
Map<String, String> map = JSON.parseObject(res, Map.class); //解析json字符串
if (null != map && !map.isEmpty()) {
try {
if (!map.containsKey("errcode")) {
obj.put("ytzhOpenId", map.get("openid"));
} else {
String errorCode = String.valueOf(map.get("errcode"));
if ("40163".equals(errorCode)) {
throw new BusinessException("链接已过期");
} else if ("40029".equals(errorCode)) {
throw new BusinessException("code无效");
}
}
} catch (Exception e) {
ExceptionLogger.error(e);
throw new BusinessException(e.getMessage());
}
}
} catch (IOException e) {
// TODO Auto-generated catch block
ExceptionLogger.error(e);
throw new BusinessException(e.getMessage());
}
return obj;
}
PS:
注意点:
此时如果你未勾选项目中的“开发环境不效验请求域名、TLS版本以及HTTPS证书”则会报错
到设置->项目设置->勾选:开发环境不校验请求域名、TLS版本以及HTTPS证书
小程序服务器域名配置常见错误:
http://kf.qq.com/faq/1706236NjINj1706236VRZBR.html