登錄簡介
第一步:獲取token
第二步:通過token拿用戶信息
第三步:調(diào)用接口獲取手機(jī)號
HttpClientUtil:
WeChatUtil:
controller層:
service層:
serviceImpl層:
登錄簡介
? ? ? ?新版本微信小程序登錄是前端獲取用戶信息,不再是后端獲取信息進(jìn)行保存。所以后端要做的主要流程就是生成token,然后通過token查看數(shù)據(jù)庫用戶信息有沒有手機(jī)號,有的話返回給前端,沒有就去調(diào)用獲取手機(jī)號接口。大致分為這三步。
第一步:獲取token
? ? ? 前端通過調(diào)取vx.login拿到code,將code傳給后端,后端將code進(jìn)行解析出session_key、openid、unionid,然后生成token,將以上信息進(jìn)行保存。(我這里是將token作為字段進(jìn)行存儲,利用session_key和openid加密生成)
第二步:通過token拿用戶信息
第三步:調(diào)用接口獲取手機(jī)號
? ? ? 這也是至關(guān)重要的一步,如果第二步獲取用戶信息中沒有手機(jī)號(這里前端判斷),后端就去獲取手機(jī)號,前端傳給后端code,后端解析code拿到手機(jī)號,再通過heahers拿到token,根據(jù)token去數(shù)據(jù)庫把手機(jī)號存到對應(yīng)的人員信息里。
上代碼!!?。。?!
HttpClientUtil:
public class HttpClientUtil {
final static int TIMEOUT = 1000;
final static int TIMEOUT_MSEC = 5 * 1000;
public static String doPost(String url, Map<String, String> paramMap) throws IOException {
// 創(chuàng)建Httpclient對象
CloseableHttpClient httpClient = HttpClients.createDefault();
//創(chuàng)建響應(yīng)對象
CloseableHttpResponse response = null;
String resultString = "";
try {
// 創(chuàng)建Http Post請求
HttpPost httpPost = new HttpPost(url);
// 創(chuàng)建參數(shù)列表
if (paramMap != null) {
List<NameValuePair> paramList = new ArrayList<>();
for (Map.Entry<String, String> param : paramMap.entrySet()) {
paramList.add(new BasicNameValuePair(param.getKey(), param.getValue()));
}
// 模擬表單
UrlEncodedFormEntity entity = new UrlEncodedFormEntity(paramList);
httpPost.setEntity(entity);
}
httpPost.setConfig(builderRequestConfig());
// 執(zhí)行請求
response = httpClient.execute(httpPost);
resultString = EntityUtils.toString(response.getEntity(), "UTF-8");
} catch (Exception e) {
throw new IOException("HttpClientUtil工具類執(zhí)行請求失敗---" + e);
} finally {
try {
response.close();
} catch (IOException e) {
throw new IOException("HttpClientUtil工具類關(guān)閉響應(yīng)資源失敗---" + e);
}
}
return resultString;
}
private static RequestConfig builderRequestConfig() {
return RequestConfig.custom()
.setConnectTimeout(TIMEOUT_MSEC)
.setConnectionRequestTimeout(TIMEOUT_MSEC)
.setSocketTimeout(TIMEOUT_MSEC).build();
}
}
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.7.16</version>
</dependency>
WeChatUtil:
這里是獲取手機(jī)號所用到的公共類,導(dǎo)包用的都是hutool的
public class WeChatUtil {
/**
* 請求微信接口服務(wù),獲取小程序全局唯一后臺接口調(diào)用憑據(jù)(access_token)
* https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/access-token/auth.getAccessToken.html
*
* @param appid
* @param secretKey
* @return
*/
public static JSONObject getAccessToken(String appid, String secretKey) {
String result = null;
try {
String baseUrl = "https://api.weixin.qq.com/cgi-bin/token";
HashMap<String, Object> requestParam = new HashMap<>();
// 小程序 appId
requestParam.put("grant_type", "client_credential");
// 小程序唯一憑證id appid
requestParam.put("appid", appid);
// 小程序 appSecret
requestParam.put("secret", secretKey);
// 發(fā)送GET請求讀取調(diào)用微信接口獲取openid用戶唯一標(biāo)識
result = HttpUtil.get(baseUrl, requestParam);
} catch (Exception e) {
e.printStackTrace();
}
return JSONUtil.parseObj(result);
}
/**
* 請求微信接口服務(wù),用code換取用戶手機(jī)號(每個code只能使用一次,code的有效期為5min)
* https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/phonenumber/phonenumber.getPhoneNumber.html
*
* @param code
* @param accessToken
* @return
*/
public static JSONObject getPhoneNumber(String code, String accessToken) {
String result = null;
try {
// 接口調(diào)用憑證:accessToken
String baseUrl = "https://api.weixin.qq.com/wxa/business/getuserphonenumber?access_token=" + accessToken;
HashMap<String, Object> requestParam = new HashMap<>();
// 手機(jī)號調(diào)用憑證
requestParam.put("code", code);
// 發(fā)送post請求讀取調(diào)用微信接口獲取openid用戶唯一標(biāo)識
String jsonStr = JSONUtil.toJsonStr(requestParam);
HttpResponse response = HttpRequest.post(baseUrl)
.header(Header.CONTENT_ENCODING, "UTF-8")
// 發(fā)送json數(shù)據(jù)需要設(shè)置contentType
.header(Header.CONTENT_TYPE, "application/x-www-form-urlencoded")
.body(jsonStr)
.execute();
if (response.getStatus() == HttpStatus.HTTP_OK) {
result = response.body();
}
} catch (Exception e) {
e.printStackTrace();
}
return JSONUtil.parseObj(result);
}
}
ApiResponseBody是我封裝的統(tǒng)一返回接口,需要替換掉?。。。。?/strong>
controller層:
@RestController
@RequestMapping("wechat/login")
public class LoginController {
@Resource
WechatService wechatService;
@Resource
WechatUserService wechatUserService;
/**
* 登錄
* @param code
* @return
* @throws Exception
*/
@ApiOperation(value = "登錄", notes = "post請求,登錄")
@PostMapping(value = "/getToken")
public ApiResponseBody login(@RequestParam("code") String code) throws Exception {
return wechatService.getUserInfoMap(code);
}
/**
* 獲取用戶信息
* @param token
* @return
*/
@ApiOperation(value = "獲取用戶信息", httpMethod = "POST")
@GetMapping(value = "/getUserDetailByToken")
public ApiResponseBody getUserDetailByToken(@RequestHeader("token") String token) {
return wechatUserService.getUserDetailByToken(token);
}
/**
*獲取用戶手機(jī)號
* @param
* @return
*/
@ApiOperation(value = "獲取用戶手機(jī)號", httpMethod = "POST")
@PostMapping("/getPhoneNumber")
public ApiResponseBody getPhoneNumber(HttpServletRequest request, @RequestParam("code") String code) {
return wechatService.getPhoneNumber(code,request);
}
}
service層:
public interface WechatService {
ApiResponseBody getUserInfoMap(String code) throws Exception;
ApiResponseBody getPhoneNumber(String code, HttpServletRequest request);
}
public interface WechatUserService {
List<Map<String, Object>> getByOpenId(String openId);
ApiResponseBody getUserDetailByToken(String token);
void update(Map<String, Object> user);
void saveUser(Map<String, Object> userMap);
void saveDictId(List<Map<String, Object>> dictMapList);
void savePhoneNumber(Map<String, Object> bodyMap);
}
serviceImpl層:
這里注意第一個接口JSONObject 導(dǎo)的是fastjson的包,獲取手機(jī)號那里用的是hutool的包
@Service
@Slf4j
public class WechatServiceImpl implements WechatService {
@Resource
private RedisTemplate redisTemplate;
@Resource
private WechatUserService wechatUserService;
private static final String REQUEST_URL = "https://api.weixin.qq.com/sns/jscode2session";
private static final String GRANT_TYPE = "authorization_code";
private static final String APPID = "";
private static final String SECRET = "";
@Override
@Transactional(rollbackFor = Exception.class)
public ApiResponseBody getUserInfoMap(String code) throws Exception {
JSONObject sessionKeyOpenId = getSessionKeyOrOpenId(code);
Assert.isTrue(sessionKeyOpenId != null, "code解析錯誤");
// 獲取openId && sessionKey && UnionID
String openId = sessionKeyOpenId.getString("openid");
Assert.isTrue(openId != null, "openId為空");
String sessionKey = sessionKeyOpenId.getString("session_key");
String unionID = sessionKeyOpenId.getString("UnionID");
// 根據(jù)openid查詢用戶
List<Map<String, Object>> user = wechatUserService.getByOpenId(openId);
String tokenData = openId + sessionKey;
String token = getToken(tokenData);
List<Map<String, Object>> dictMapList = new ArrayList<>();
Map<String, Object> userMap = new HashMap<>();
userMap.put("openId", openId );
userMap.put("token", token);
userMap.put("unionId", unionID);
//如果不存在用戶就去添加,存在就修改token
if (user.size() == 0) {
wechatUserService.saveUser(userMap);
} else {
wechatUserService.update(userMap);
}
return ApiResponseBody.defaultSuccess(token);
}
@Override
public ApiResponseBody getPhoneNumber(String code, HttpServletRequest request) {
// 1.請求微信接口服務(wù),獲取accessToken
cn.hutool.json.JSONObject accessTokenJson = WeChatUtil.getAccessToken(APPID, SECRET);
String accessToken = accessTokenJson.get("access_token",String.class);
// 2.請求微信接口服務(wù),獲取用戶手機(jī)號信息
cn.hutool.json.JSONObject phoneNumberJson = WeChatUtil.getPhoneNumber(code, accessToken);
WeChatPhoneInfo phoneInfo = phoneNumberJson.get("phone_info", WeChatPhoneInfo.class);
Map<String, Object> bodyMap = new HashMap<>();
String token = request.getHeader("token");
bodyMap.put("phoneNumber", phoneInfo.getPurePhoneNumber());
bodyMap.put("token", token);
wechatUserService.savePhoneNumber(bodyMap);
return ApiResponseBody.defaultSuccess(phoneInfo.getPurePhoneNumber());
}
private JSONObject getSessionKeyOrOpenId(String code) throws Exception {
Map<String, String> requestUrlParam = new HashMap<>();
requestUrlParam.put("appid", APPID);
requestUrlParam.put("secret", SECRET);
requestUrlParam.put("js_code", code);
// 默認(rèn)參數(shù)
requestUrlParam.put("grant_type", GRANT_TYPE);
// 發(fā)送post請求讀取調(diào)用微信接口獲取openid用戶唯一標(biāo)識
String result = HttpClientUtil.doPost(REQUEST_URL, requestUrlParam);
return JSON.parseObject(result);
}
/**
* 這里的 token 使用 SHA-256哈希算法生成
* @param data
* @return
* @throws NoSuchAlgorithmException
*/
private static String getToken(String data) throws NoSuchAlgorithmException {
MessageDigest digest = MessageDigest.getInstance("SHA-256");
byte[] hash = digest.digest(data.getBytes());
StringBuilder hexString = new StringBuilder();
for (byte b : hash) {
String hex = Integer.toHexString(0xff & b);
if (hex.length() == 1) {
hexString.append('0');
}
hexString.append(hex);
}
return hexString.toString();
}
}
最后還有一個WechatUserServiceImpl,這個主要做的就是增刪改查的操作,所以這里就不展示了,前面說的很詳細(xì),只要按照流程一步一步走,然后寫SQL就沒問題。文章來源:http://www.zghlxwxcb.cn/news/detail-855955.html
完結(jié)撒花? 歡迎評論區(qū)討論文章來源地址http://www.zghlxwxcb.cn/news/detail-855955.html
到了這里,關(guān)于【微信小程序】實現(xiàn)微信小程序登錄(附源碼)后端,微信小程序獲取手機(jī)號的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!