微信登入及获取微信手机号

第三方登入现在以及非常普遍了,所以在此记录微信登入的现实方式

看图

说明:

  1. 调用 wx.login() 获取 临时登录凭证code ,并回传到开发者服务器。
  2. 调用 code2Session 接口,换取 用户唯一标识 OpenID 和 会话密钥 session_key

之后开发者服务器可以根据用户标识来生成自定义登录态,用于后续业务逻辑中前后端交互时识别用户身份。

注意:

  1. 会话密钥 session_key 是对用户数据进行 加密签名 的密钥。为了应用自身的数据安全,开发者服务器不应该把会话密钥下发到小程序,也不应该对外提供这个密钥
  2. 临时登录凭证 code 只能使用一次

具体代码

wx.login({
  success(res) {
    if (res.code) {
      // 发起网络请求
      wx.request({
        url: 'https://test.com/onLogin',
        data: {
          code: res.code//将code传入的服务端
        }
      })
    } else {
      console.log('登录失败!' + res.errMsg)
    }
  }
})

//获取到code

//Java代码
//appid,secret 保存在服务端

OkHttpClient client = new OkHttpClient();
Request okrequest = new Request.Builder()
.url("https://api.weixin.qq.com/sns/jscode2session?appid=" + WeiXinConfig.APP_ID + "&secret="+ WeiXinConfig.SECRET + "&js_code=" + request.getCode() + "&grant_type=authorization_code").get().addHeader("cache-control", "no-cache").build();

try {
	Response response = client.newCall(okrequest).execute();
	if (200 != response.code()) {
	    throw new BizException("获取微信用户信息失败");
	}
	String openkey = response.body().string();
	JSONObject open = JSONObject.parseObject(openkey);
	String openid = open.getString("openid");
	if (StringUtils.isEmpty(openid)) {
		throw new BizException("获取微信openid失败");
	}
user = userExtendsMapper.selectUserByOpenId(openid);
userProfile.setUserId(user.getId());
String us = JSONObject.toJSON(userProfile).toString();
try {
	createJWT = TokenUtil.createJWT(UUIDGenerator.getUUID(), us, Constant.JWT_TTL);
} catch (Exception e) {
	throw new BizException("生成token失败");
}

//生产服务token,用于微信小程序与服务器交互

 

接下来就是采用session_key去获取手机号码了

需要将 <button> 组件 open-type 的值设置为 getPhoneNumber,当用户点击并同意之后,可以通过 bindgetphonenumber 事件回调获取到微信服务器返回的加密数据, 然后在第三方服务端结合 session_key 以及 app_id 进行解密获取手机号。

Page({
  getPhoneNumber(e) {
    console.log(e.detail.errMsg)
    console.log(e.detail.iv)
    console.log(e.detail.encryptedData)

    }
  }
})

//Java服务器端代码 获取session-key  code是前端调用login()方法获取到传入后台的
public static String getSeesionKey(String code) {
String sessionKey = null;
OkHttpClient client = new OkHttpClient();
Request okrequest = new Request.Builder()
.url("https://api.weixin.qq.com/sns/jscode2session?appid=" + WeiXinConfig.APP_ID + "&secret="+ WeiXinConfig.SECRET + "&js_code=" + code + "&grant_type=authorization_code").get().addHeader("cache-control", "no-cache").build();

Response response;
	try {
		response = client.newCall(okrequest).execute();
		if (200 != response.code()) {
				throw new BizException("获取微信用户信息失败");
		}
		String openkey = response.body().string();
		JSONObject open = JSONObject.parseObject(openkey);
		sessionKey = open.getString("session_key");
		if (StringUtils.isEmpty(sessionKey)) {
				throw new BizException("获取微信sessionKey失败");
		}
	} catch (IOException e) {
		throw new BizException("获取微信sessionKey失败");
	}
	return sessionKey;
}

//解密方法
public static String decrypt(String encrypted, String session_key, String iv) throws Exception {

	byte[] encrypData = Base64.decodeBase64(encrypted);
	byte[] ivData = Base64.decodeBase64(iv);
	byte[] sessionKey = Base64.decodeBase64(session_key);
//	byte[] sessionKey = Base64.decodeBase64("Fn6r4IOiZJBXn4hQ0w==");
	AlgorithmParameterSpec ivSpec = new IvParameterSpec(ivData);
	Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
	SecretKeySpec keySpec = new SecretKeySpec(sessionKey, "AES");
	cipher.init(Cipher.DECRYPT_MODE, keySpec, ivSpec);
	// 解析解密后的字符串
	return new String(cipher.doFinal(encrypData), "UTF-8");
}

//前台传入code,encrypted,iv 
public String getPhone(GetPhoneRequestBody request) {
	String seesionKey = AESDecodeUtils.getSeesionKey(request.getCode());
	String decrypt;
	try {
		decrypt = AESDecodeUtils.decrypt(request.getEncrypted(), seesionKey, request.getIv());
	} catch (Exception e) {
		throw new BizException("解密失败");
	}
    //返回格式
    //{
    //  "phoneNumber": "13580006666",
    //  "purePhoneNumber": "13580006666",
    //  "countryCode": "86",
    //  "watermark": {
    //   "appid": "APPID",
    //   "timestamp": TIMESTAMP
    //  }
	JSONObject open = JSONObject.parseObject(decrypt);
	String phoneNumber = open.getString("phoneNumber");
	if (StringUtils.isEmpty(phoneNumber)) {
		throw new BizException("获取微信手机号失败");
	}
	return phoneNumber;
}

最后返回phone给前端

 

  • 6
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值