? ? ? ? 最近做了一個(gè)關(guān)于商城的項(xiàng)目,B端選用若依的開源框架,C端還是vue前后端分離。其中C端主要是小程序的形式,所以想著來總結(jié)一下對(duì)接微信小程序登錄中Java部分遇到的坑即代碼分享!
廢話不多說,直接上代碼!
1、controller 層代碼
? ? ? ??入?yún)⑽疫@邊是直接使用request來接收,大家可以改成自己的DTO來接收入?yún)?/p>
@GetMapping("/letsLogin")
@ApiOperation("微信授權(quán)登錄")
public R letsLogin(HttpServletRequest request){
return remoteMallUserService.letsLogin(request);
}
2、service 層代碼
????????其中涉及到幾個(gè)基本配置參數(shù),我這邊單獨(dú)列出,大家可以放入配置文件進(jìn)行引用,也可以直接作為常量引用;
同時(shí)可以參考微信公眾平臺(tái)提供的開發(fā)文檔(服務(wù)端):接口調(diào)用憑證 | 微信開放文檔
// APP_ID 小程序注冊時(shí)由微信提供
private final static String APP_ID = "....";
// APP_SERCRET 小程序注冊時(shí)由微信提供
private final static String APP_SERCRET = ".....";
// 請求地址這邊用了多個(gè)所以我們按照調(diào)用的順序來說明
// 首先是這個(gè)TOKENURL 用于獲取微信用戶的授權(quán)認(rèn)證 來拿到“accessToken”
private final static String TOKENURL = "https://api.weixin.qq.com/cgi-bin/token";
// 第二是用于請求獲取用戶手機(jī)號(hào)的地址(結(jié)尾的“access_token”需要拼接上TOKENURL返回的參數(shù))
private final static String PHONENURL = "https://api.weixin.qq.com/wxa/business/getuserphonenumber?access_token=";
// 最后才是登錄url了
private final static String URL = "https://api.weixin.qq.com/sns/jscode2session";
????????由于我自身的業(yè)務(wù)中存在通過手機(jī)號(hào)驗(yàn)證登錄這個(gè)功能模塊,所以我在入?yún)⒌臅r(shí)候會(huì)做一個(gè)是否存在手機(jī)號(hào)的判斷,不存在時(shí)才通過微信去請求;存在時(shí)直接調(diào)用登錄URL即可;
?這邊還需要簡單解釋一下入?yún)?span style="color:#be191c;">(紅色為必傳參數(shù)):
? ? ? ? 1、userPhone? 用戶手機(jī)號(hào);
? ? ? ? 2、code:前端通過getPhoneNum() 獲得的code;
? ? ? ? 3、loginCode:前端通過wx.login() 獲得的code;
@Autowired
private RestTemplate restTemplate;
@Override
public R letsLogin(HttpServletRequest request){
// 先拿到前端通過wx.login()拿到的code -- 5分鐘過期哦
String loginCode = request.getParameter("loginCode");
if(StringUtils.isBlank(loginCode)){
return R.fail(101,"loginCode不可以為空!");
}
String userPhone = request.getParameter("userPhone");
// 如果手機(jī)號(hào)為空則判斷是否有code(該code是前端通過獲取手機(jī)號(hào)方法拿到的)
if (StringUtils.isBlank(userPhone)){
String code = request.getParameter("code");
if(StringUtils.isBlank(code)){
return R.fail(101,"code為空,無法獲取手機(jī)號(hào)!");
}
// 獲取手機(jī)號(hào) -- 這邊需要定義一個(gè)傳參的map
Map<String, String> params1 = new HashMap<>();
// 此處為固定值不需要修改
params1.put("grant_type", "client_credential");
// APP_ID和APP_SERCRET需要根據(jù)實(shí)際情況進(jìn)行傳參
params1.put("appid", APP_ID);
params1.put("secret", APP_SERCRET);
// 調(diào)用TOKENURL獲取授權(quán)憑證access_token
// 我這邊用的是Hultool的HTTP請求工具 -- 之后會(huì)附上maven依賴
String resultToken = HttpUtil.sendGet(TOKENURL, params1);
// fastjson 框架自帶 大家可以選擇自己的JSON轉(zhuǎn)換工具
JSONObject tokenJson = JSONObject.parseObject(resultToken);
String accessToken = (String)tokenJson.get("access_token");
// 使用前端code獲取手機(jī)號(hào)碼(accessToken一定要以get的方式請求)其他參數(shù)為json格式
String url1 = PHONEURL + accessToken;
Map<String, String> paramMap = new HashMap<>();
paramMap.put("code", code);
HttpHeaders headers = new HttpHeaders();
HttpEntity<Map<String, String>> httpEntity = new HttpEntity<>(paramMap, headers);
ResponseEntity<Object> response = restTemplate.postForEntity(url1, httpEntity, Object.class);
Object body = response.getBody();
Map<String, Object> map = new ObjectMapper().convertValue(body, Map.class);
Object phoneInfo = map.get("phone_info");
Map<String, Object> map1 = new ObjectMapper().convertValue(phoneInfo, Map.class);
// 以上都是response參數(shù)的處理 最終拿到userPhone 可以進(jìn)行下一步 微信登陸了
userPhone = (String)map1.get("phoneNumber");
}
// 構(gòu)建 一個(gè)map傳登錄的參數(shù)
Map<String, String> params = new HashMap<>();
params.put("appid", APP_ID);
params.put("secret", APP_SERCRET);
// 這里的code是前端通過wx.login()獲取到的
params.put("js_code", loginCode);
// 固定參數(shù)
params.put("grant_type", "authorization_code");
String resultJson = HttpUtil.sendGet(URL, params);
JSONObject json = JSONObject.parseObject(resultJson);
if (!json.containsKey("errcode")) {
// 拿到openid(用戶在該小程序的唯一用戶標(biāo)識(shí))
String openId = (String)json.get("openid");
// 之后的可以根據(jù)自己的業(yè)務(wù)進(jìn)行處理 比如:新增用戶...
return R.ok("","登錄成功");
} else {
return R.fail(101,"登錄失??!");
}
}
3、util 層代碼。添加一個(gè)RestTemplateConfig配置類
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.client.ClientHttpRequestFactory;
import org.springframework.http.client.SimpleClientHttpRequestFactory;
import org.springframework.web.client.RestTemplate;
@Configuration
public class RestTemplateConfig {
@Bean
public RestTemplate restTemplate() {
return new RestTemplate();
}
@Bean
public ClientHttpRequestFactory simpleClientHttpRequestFactory() {
SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory();
factory.setReadTimeout(5000);//ms
factory.setConnectTimeout(15000);//ms
return factory;
}
}
4、Hultool的依賴文章來源:http://www.zghlxwxcb.cn/news/detail-445294.html
<!-- hutool 工具包-->
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.2.4</version>
</dependency>
? ? ? ? 最后說一下在開發(fā)中踩到的坑,就是獲取手機(jī)號(hào)返回的response這邊進(jìn)行了兩次的map轉(zhuǎn)換才拿到最終的手機(jī)號(hào),但是官方文檔中的返回格式是一個(gè)JSON對(duì)象,如果是一個(gè)JSON串的話就不需要這么麻煩了,所以各位大神可以在開發(fā)的時(shí)候優(yōu)化一下這部分!文章來源地址http://www.zghlxwxcb.cn/news/detail-445294.html
到了這里,關(guān)于Java - 微信小程序授權(quán)手機(jī)號(hào)登錄的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!