springboot对接微信小程序登录接口

后端对接微信小程序登录接口

后端代码如下:


@RestController
@Api(tags = "登录-小程序")
@RequestMapping("/api/app")
public class AppEbLoginController {

    //这两个需要提前配置好
    //小程序appId
    private String appId;

    //小程序appSecret
    private String appSecret;



    @PostMapping("/login")
    public CommonResult<Map> login(@RequestBody Map<String,String> request){

        //小程序需要传来一个code
        String code = request.get("code");

        //调用微信小程序登录接口
        String url = "https://api.weixin.qq.com/sns/jscode2session?appid=" + appId +
                "&secret=" + appSecret +
                "&js_code=" + code +
                "&grant_type=authorization_code";
        RestTemplate restTemplate = new RestTemplate();

        ResponseEntity<String> responseEntity = restTemplate.getForEntity(url, String.class);
        Map<String, Object> map = JSONObject.parseObject(responseEntity.getBody(), new TypeReference<Map<String, Object>>() {});
        //获得响应的数据
        Map<String,Object> responseBody = map;

        //if (responseBody.get("errcode")!=null&&responseBody.get("errcode").equals(40029)){
         //   return CommonResult.failed("code 无效");
       // }
        // 解密用户信息
        String encryptedData = request.get("encryptedData");
        String iv = request.get("iv");
        String sessionKey = (String) responseBody.get("session_key");
        Map<String, Object> userInfo = getDecryptedUserInfo(encryptedData, sessionKey, iv);

  		//这里可以对用户信息进行一些操作
        
        return  CommonResult.success(userInfo);
    }

	//解密
    private Map<String, Object> getDecryptedUserInfo(String encryptedData, String sessionKey, String iv) {
        byte[] encryptedDataByte = Base64.decodeBase64(encryptedData);
        byte[] sessionKeyByte = Base64.decodeBase64(sessionKey);
        byte[] ivByte = Base64.decodeBase64(iv);

        try {
            Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
            SecretKeySpec secretKeySpec = new SecretKeySpec(sessionKeyByte, "AES");
            IvParameterSpec ivParameterSpec = new IvParameterSpec(ivByte);
            cipher.init(Cipher.DECRYPT_MODE, secretKeySpec, ivParameterSpec);
            byte[] decryptedByte = cipher.doFinal(encryptedDataByte);
            String decryptedData = new String(decryptedByte, StandardCharsets.UTF_8);

            // 将解密后的数据转为Map
            ObjectMapper mapper = new ObjectMapper();
            return mapper.readValue(decryptedData, Map.class);
        } catch (Exception e) {
            e.printStackTrace();
        }

        return new HashMap<>();
    }

}

微信小程序的登录,这里只涉及到后端代码,所以默认你是申请了一个小程序并且有了appid和secret。

官方说明文档:https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/login.html

img

首先由小程序端调用wx.login()去获取code,然后,再通过wx.getUserInfo()去获取用户信息(这里请求login和getUserInfo是一起的,把这两次请求的数据合并发给后端的login接口),通过请求,把:

1.code //临时登入凭证
// 如果不同意获取用户信息,则下面四个参数获取不到
2.rawData //用户非敏感信息,头像和昵称之类的
3.signature //签名
4.encryteDate //用户敏感信息,需要解密,(包含unionID)
5.iv //解密算法的向量

给到服务端,服务端根据 appid+secret+js_code+grant_type 去请求https://api.weixin.qq.com/sns/jscode2session,获取到session_key和openid(这里无法获取unionID),通过session_key,iv来解密encrypteDate获取用户敏感信息和unionID,把用户信息保存到数据库。然后,我们可以把sesssoin_key和openid保存下来,与token来进行关联,最后把小程序需要的数据返回给小程序端,以后就通过token来维护用户登入状态。

(我这里的代码并没有生成token,也没有保存到数据库)

请添加图片描述
请添加图片描述
一些注意事项:

  • code是有时效行的,5分钟内有效,并且只能使用一次
  • token的实现,以及token过期时间,token放在数据库中还是缓存中,token是否每次登入都需要刷新?这么些个问题,自己结合业务需求来做判断。
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值