登录简介
第一步:获取token
第二步:通过token拿用户信息
第三步:调用接口获取手机号
HttpClientUtil:
WeChatUtil:
controller层:
service层:
serviceImpl层:
登录简介
新版本微信小程序登录是前端获取用户信息,不再是后端获取信息进行保存。所以后端要做的主要流程就是生成token,然后通过token查看数据库用户信息有没有手机号,有的话返回给前端,没有就去调用获取手机号接口。大致分为这三步。
第一步:获取token
前端通过调取vx.login拿到code,将code传给后端,后端将code进行解析出session_key、openid、unionid,然后生成token,将以上信息进行保存。(我这里是将token作为字段进行存储,利用session_key和openid加密生成)
第二步:通过token拿用户信息
第三步:调用接口获取手机号
这也是至关重要的一步,如果第二步获取用户信息中没有手机号(这里前端判断),后端就去获取手机号,前端传给后端code,后端解析code拿到手机号,再通过heahers拿到token,根据token去数据库把手机号存到对应的人员信息里。
上代码!!!!!!
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 {
// 创建Httpclient对象
CloseableHttpClient httpClient = HttpClients.createDefault();
//创建响应对象
CloseableHttpResponse response = null;
String resultString = "";
try {
// 创建Http Post请求
HttpPost httpPost = new HttpPost(url);
// 创建参数列表
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());
// 执行请求
response = httpClient.execute(httpPost);
resultString = EntityUtils.toString(response.getEntity(), "UTF-8");
} catch (Exception e) {
throw new IOException("HttpClientUtil工具类执行请求失败---" + e);
} finally {
try {
response.close();
} catch (IOException e) {
throw new IOException("HttpClientUtil工具类关闭响应资源失败---" + 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:
这里是获取手机号所用到的公共类,导包用的都是hutool的
public class WeChatUtil {
/**
* 请求微信接口服务,获取小程序全局唯一后台接口调用凭据(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);
// 发送GET请求读取调用微信接口获取openid用户唯一标识
result = HttpUtil.get(baseUrl, requestParam);
} catch (Exception e) {
e.printStackTrace();
}
return JSONUtil.parseObj(result);
}
/**
* 请求微信接口服务,用code换取用户手机号(每个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 {
// 接口调用凭证:accessToken
String baseUrl = "https://api.weixin.qq.com/wxa/business/getuserphonenumber?access_token=" + accessToken;
HashMap<String, Object> requestParam = new HashMap<>();
// 手机号调用凭证
requestParam.put("code", code);
// 发送post请求读取调用微信接口获取openid用户唯一标识
String jsonStr = JSONUtil.toJsonStr(requestParam);
HttpResponse response = HttpRequest.post(baseUrl)
.header(Header.CONTENT_ENCODING, "UTF-8")
// 发送json数据需要设置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是我封装的统一返回接口,需要替换掉!!!!!
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);
}
/**
*获取用户手机号
* @param
* @return
*/
@ApiOperation(value = "获取用户手机号", 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 导的是fastjson的包,获取手机号那里用的是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");
// 根据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.请求微信接口服务,获取accessToken
cn.hutool.json.JSONObject accessTokenJson = WeChatUtil.getAccessToken(APPID, SECRET);
String accessToken = accessTokenJson.get("access_token",String.class);
// 2.请求微信接口服务,获取用户手机号信息
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);
// 默认参数
requestUrlParam.put("grant_type", GRANT_TYPE);
// 发送post请求读取调用微信接口获取openid用户唯一标识
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,这个主要做的就是增删改查的操作,所以这里就不展示了,前面说的很详细,只要按照流程一步一步走,然后写SQL就没问题。文章来源:https://www.toymoban.com/news/detail-855955.html
完结撒花 欢迎评论区讨论文章来源地址https://www.toymoban.com/news/detail-855955.html
到了这里,关于【微信小程序】实现微信小程序登录(附源码)后端,微信小程序获取手机号的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!