微信小程序获取openid

版权声明: https://blog.csdn.net/qq_15901351/article/details/82156129

微信官方文档:小程序-开放接口-登录

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

可以参考:https://blog.csdn.net/llayjun/article/details/78291641

猜你喜欢

转载自blog.csdn.net/qq_15901351/article/details/82156129