微信小程序登录和获取手机号

目录

准备工作

实现流程

实现代码

公共部分

通过code获取openid等信息

解密手机号

扩展

不借助工具类实现解密

借助工具类获取access_token


准备工作

需要小程序账号(可以去微信公众平台创建一个测试号或者正式号)

  • appid:小程序id

  • appsecret:小程序密钥,

需要工具

  • HBuilder X(用来启动小程序代码的)

  • 微信开发者工具(用来调试小程序的)

只有后端的实现,没有前端的代码

实现流程

1.首先需要前端在小程序中调用wx.login去获取code

2.前端将code交给后端,后端使用code,appid,sectret调用微信的api获取openid和session_key(用来解密用的),union_id(要注册到微信开放平台才会有)

https://api.weixin.qq.com/sns/jscode2session?appid=小程序id&secret=小程序密钥&js_code=前端传递的code&grant_type=authorization_code

我们获取到了openid去数据库查询是否存在,如果存在直接返回token完成登录

如果数据库中并没有这个openid,需要进行第三步后的操作,获取用户基本信息和手机号进行注册

3.返回数据给前端,让前端通过使用wx.getUserInfo接口或者wx.getUserProfile(官方推荐这种,前面那个快要废弃)接口跳转到授权页面,获取用户的基本数据userInfo,和加密后的手机号数据encryptedData 以及 iv(小程序测试号不能获取手机号授权)

4.前端将获取到的userInfo 和 encryptedData 以及 iv交给后端,后端将通过code获取到的session_key配合encryptedData 和iv对手机号进行解密,然后将获取到的手机号,基本信息,openid等信息进行注册后,返回前端token注册登录完成

5.完成

实现代码

下面的代码使用的是微信的sdk实现方式(提供了很多工具类,不需要我们定义解密等代码,直接调用sdk中的方法,非常非常非常简单)

公共部分

复制代码
WxMaDefaultConfigImpl config = new WxMaDefaultConfigImpl();
// 替换为你的小程序 appId
config.setAppid("your_app_id");
// 替换为你的小程序 appSecret
config.setSecret("your_app_secret");

WxMaService service = new WxMaServiceImpl();
service.setWxMaConfig(config)

通过code获取openid等信息

service是上面公共部分定义的

复制代码
//code是前端返回的
WxMaJscode2SessionResult wxMaJscode2SessionResult = service.getUserService().getSessionInfo(code);
String openid = wxMaJscode2SessionResult.getOpenid;
String sessionKey = wxMaJscode2SessionResult.getSessionKey;

解密手机号

service是上面公共部分定义的

复制代码
//sessionKey通过code换取的
//encryptedData, iv前端返回的
WxMaPhoneNumberInfo phoneNumberInfo = wxMaService.getUserService().getPhoneNoInfo(sessionKey, encryptedData, iv);
String phoneNumber = phoneNumberInfo.getPhoneNumber();

扩展

不借助工具类实现解密

复制代码
public static String decryptData(String encryptedData, String sessionKey, String iv) throws Exception {
        // 解密
  byte[] encryptedDataBytes = Base64.getDecoder().decode(encryptedData);
  byte[] sessionKeyBytes = Base64.getDecoder().decode(sessionKey);
  byte[] ivBytes = Base64.getDecoder().decode(iv);

  Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
  SecretKeySpec secretKeySpec = new SecretKeySpec(sessionKeyBytes, "AES");
  IvParameterSpec ivParameterSpec = new IvParameterSpec(ivBytes);
  cipher.init(Cipher.DECRYPT_MODE, secretKeySpec, ivParameterSpec);
  byte[] decryptedBytes = cipher.doFinal(encryptedDataBytes);

  return new String(decryptedBytes);
}

借助工具类获取access_token

service是上面公共部分定义的

复制代码
String accessToken = service.getAccessToken();
相关推荐
陈文锦丫18 小时前
MQ的学习
java·开发语言
乌暮18 小时前
JavaEE初阶---线程安全问题
java·java-ee
爱笑的眼睛1119 小时前
GraphQL:从数据查询到应用架构的范式演进
java·人工智能·python·ai
Seven9719 小时前
剑指offer-52、正则表达式匹配
java
代码or搬砖19 小时前
RBAC(权限认证)小例子
java·数据库·spring boot
青蛙大侠公主19 小时前
Thread及其相关类
java·开发语言
Coder_Boy_19 小时前
DDD从0到企业级:迭代式学习 (共17章)之 四
java·人工智能·驱动开发·学习
2301_7683502319 小时前
MySQL为什么选择InnoDB作为存储引擎
java·数据库·mysql
派大鑫wink20 小时前
【Java 学习日记】开篇:以日记为舟,渡 Java 进阶之海
java·笔记·程序人生·学习方法