小程序登录,通过code获取openId 或者通过code或者手机号码(新版)
小程序的登录,通过前端传过来code,在服务端(java)获取openId返回给前端进行登录。
首先你得有appid以及secret(秘钥).
下面是业务逻辑代码(这里为了方便展示直接写在了controller)
@GetMapping("getCode")
public AjaxResult getCode(String code){
// 授权(必填)
String wxspAppid = "填写小程序appid";
String wxspSecret = "填写小程序密钥";
//默认是authorization_code
String grant_type = "authorization_code";
// 请求参数
String params = "appid=" + wxspAppid + "&secret=" + wxspSecret + "&js_code=" + code + "&grant_type=" + grant_type;
// 发送请求
String sr = HttpRequest.sendPost("https://api.weixin.qq.com/sns/jscode2session", params);
// 解析相应内容(转换成json对象)
JSONObject json = JSONObject.parseObject(sr);
logger.info("解析code请求结果:"+json.toString());
// 获取会话密钥(session_key)
//String session_key = json.getString("session_key");
//获取openId
String openid = json.getString("openid");
return AjaxResult.success(openid);
}
JSONObject 引入的是alibaba的jar
import com.alibaba.fastjson.JSONObject;
依赖
<!-- alibaba json 工具 --> <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> </dependency>
HttpRequest工具类类
/** * 向指定 URL 发送POST方法的请求 * * @param url * 发送请求的 URL * @param param * 请求参数,请求参数应该是 name1=value1&name2=value2 的形式。 * @return 所代表远程资源的响应结果 */ public static String sendPost(String url, String param) { PrintWriter out = null; BufferedReader in = null; String result = ""; try { URL realUrl = new URL(url); // 打开和URL之间的连接 URLConnection conn = realUrl.openConnection(); // 设置通用的请求属性 conn.setRequestProperty("accept", "*/*"); conn.setRequestProperty("connection", "Keep-Alive"); conn.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)"); // 发送POST请求必须设置如下两行 conn.setDoOutput(true); conn.setDoInput(true); // 获取URLConnection对象对应的输出流 out = new PrintWriter(conn.getOutputStream()); // 发送请求参数 out.print(param); // flush输出流的缓冲 out.flush(); // 定义BufferedReader输入流来读取URL的响应 in = new BufferedReader(new InputStreamReader(conn.getInputStream())); String line; while ((line = in.readLine()) != null) { result += line; } } catch (Exception e) { System.out.println("发送 POST 请求出现异常!" + e); e.printStackTrace(); } // 使用finally块来关闭输出流、输入流 finally { try { if (out != null) { out.close(); } if (in != null) { in.close(); } } catch (IOException ex) { ex.printStackTrace(); } } return result; }
新版本,通过code去获取手机号码
//新版本 public String getPhoneByCode(String code) { ResponseEntity<String> responseEntity = restTemplate.getForEntity(weChatConfig.getApiAddress() + "/cgi-bin/token?grant_type={grant_type}&appid={appid}&secret={secret}", String.class, weChatConfig.getClientCredential(), weChatConfig.getAppId(), weChatConfig.getSecretKey()); //ResponseEntity<String> responseEntity = restTemplate.getForEntity("https://api.weixin.qq.com/cgi-bin/token?grant_type={grant_type}&appid={appid}&secret={secret}", String.class, params); log.info("获取wxtoken结果集 {}", responseEntity); Map map = JSONObject.parseObject(responseEntity.getBody(), Map.class); if (!StringUtils.isEmpty(map.get("errcode"))) { throw new DefaultException("获取token参数有误"); } if (!StringUtils.isEmpty(map.get("access_token"))) { String accessToken = map.get("access_token").toString(); Map<String, String> param = new HashMap<>(); if (!StringUtils.isEmpty(code)) { param.put("code", code); } HttpHeaders headers = new HttpHeaders(); headers.setContentType(MediaType.APPLICATION_JSON); headers.set("Accept", "application/json"); HttpEntity<Map<String, String>> httpEntity = new HttpEntity<Map<String, String>>(param, headers); String url = weChatConfig.getApiAddress() + "/wxa/business/getuserphonenumber?access_token=" + accessToken; ResponseEntity<String> postResponseEntity = restTemplate.postForEntity(url, httpEntity, String.class); log.info("获取postResponseEntity结果集 {}", postResponseEntity); log.info("根据code过获取手机号码返回值 {}", postResponseEntity.getBody()); Map postMap = JSONObject.parseObject(postResponseEntity.getBody(), Map.class); log.info("根据code过获取手机号码返回值转json {}", postMap); // 使用Jackson库将JSON字符串解析为Map ObjectMapper objectMapper = new ObjectMapper(); Map<String, Object> resultMap = null; try { resultMap = objectMapper.readValue(postResponseEntity.getBody(), Map.class); } catch (JsonProcessingException e) { e.printStackTrace(); } Map<String, Object> phoneInfo = (Map<String, Object>) resultMap.get("phone_info"); log.info("objectMapper返回成功 {}", phoneInfo); assert postMap != null; if (!StringUtils.isEmpty(postMap.get("errcode"))) { String errcode = postMap.get("errcode").toString(); if (WxLoginEnum.SYSTEM_BUSY.getCode().equals(errcode)) { throw new DefaultException(WxLoginEnum.SYSTEM_BUSY.getValue()); } if (WxLoginEnum.EXPIRED.getCode().equals(errcode)) { throw new DefaultException(WxLoginEnum.EXPIRED.getValue()); } if (WxLoginEnum.ILLEGALITY.getCode().equals(errcode)) { throw new DefaultException(WxLoginEnum.ILLEGALITY.getValue()); } if (WxLoginEnum.SUCCESS.getCode().equals(errcode)) { return phoneInfo.get("phoneNumber").toString(); } } } throw new DefaultException("未获取到手机号"); }
WxLoginEnum
public enum WxLoginEnum { SYSTEM_BUSY("-1", "系统繁忙,请稍后重试"), EXPIRED("40029", "code不存在或已过期,请重试"), ILLEGALITY("40013", "不合法AppId"), SUCCESS("0", "成功"); private String code; private String value; WxLoginEnum(String code, String value) { this.code = code; this.value = value; } public String getCode() { return code; } public String getValue() { return value; } }
配置
client-credential: client_credential login-address: https://api.weixin.qq.com/sns/jscode2session api-address: https://api.weixin.qq.com
appid和秘钥跟之前的一样
好了,有问题的小伙伴请留言哦!
如遇到问题进qq群讨论:837146509