SpringBoot整合uni-app 小程序登录

微信小程序登录流程涉及到三个角色:小程序、开发者服务器、微信服务器
SpringBoot整合uni-app 小程序登录

SpringBoot整合uni-app 小程序登录

1、小程序初次启动,校验当前用户是否合法:

<script>
	const baseUrl = 'http://192.168.1.9:8082'; // 请求地址
	export default {
		onLaunch: function() {
			console.log('App Launch')
			
			uni.login({
				provider: 'weixin',
				success: function(loginRes) {
					//console.log(loginRes);   //获取code				
						    wx.request({
								url: baseUrl + '/miniprogram/user/checkOpenID',   //校验openId
								method: 'POST',
								header: {
								  'content-type': 'application/x-www-form-urlencoded'
								},
								data: {
								    code: loginRes.code //临时登录凭证
								    // rawData: info_res.rawData, //用户非敏感信息
								    // signature: info_res.signature, //签名
								    // encrypteData: info_res.encryptedData, //用户敏感信息
								    // iv: info_res.iv //解密算法的向量
								},
								success: function(res) {
								  if (res.data.status == 200) {
									//console.log(res.data.msg);
									//   这里放行
									let loginUser = uni.getStorageSync('loginInfo');
									if(!loginUser){
										loginUser = res.data.data;
										
										let json = {};
										json.f_user_id = loginUser.userId;
										json.skey = loginUser.skey;
										json.sessionKey = loginUser.sessionKey;;
										......
										uni.setStorageSync('loginInfo', json);
										
										console.log('*** App.vue print: ***');
										console.log(json);
									}else {
										console.log('*** This is from App.vue ***');
										console.log(loginUser);
										// 每次小程序执行onLaunch, 即使uni.getStorageSync有值,这里也执行uni.setStorageSync,防止过期,是否合理? todo
										uni.setStorageSync('loginInfo', loginUser);
									}
								  } else{
									// 跳转至登录页  
									console.log(res.data.msg);
									uni.navigateTo({
										url:'/pages/login/login',
										fail: (res) => {
											console.log(res)
										}
									})
								  }
								},
								fail: function(error) {
								  //调用服务端登录接口失败   跳转至登录页  
								  console.log(error);
								}
						  })

						//}
				    //})	
				}
			})
		},
		onShow: function() {
			console.log('App Show')
		},
		onHide: function() {
			console.log('App Hide')
		}
	}
</script>

2、 后台Controller方法checkOpenID:判断用户openId是否已经与用户相关联

String openid = SessionKeyOpenId.getString("openid");
if(StringUtils.isNotEmpty(openid)){
     sysUser = iSysUserService.selectUserByOpenId(openid); //根据openID获取用户
     if(sysUser != null && StringUtils.isNotEmpty(sysUser.getUserName())){
         result = GlobalResult.build(200, "账户信息正常", sysUser);
         return result;
     }
 }

3、后台登录方法login,说白了就是将当前用户openId存储到用户表对应的那个用户信息里面

/**
     * 小程序端用户登录
     */
    @PostMapping("login")
    public GlobalResult user_login(@RequestParam(value = "code", required = false) String code,
                                   @RequestParam(value = "username", required = false) String username,
                                   @RequestParam(value = "password", required = false) String password,
                                   @RequestParam(value = "avatarUrl", required = false) String avatarUrl) {
        log.info("*** user_login ***");
        GlobalResult result = GlobalResult.build(HttpStatus.UNAUTHORIZED, "账号信息有误", "");
        if(StringUtils.isEmpty(username.trim()) || StringUtils.isEmpty(password.trim())){
            log.info("*** param  is wrong  ***");
            return result;
        }

        // 1.接收小程序发送的code
        // 2.开发者服务器 登录凭证校验接口 appi + appsecret + code
        JSONObject SessionKeyOpenId = WechatUtil.getSessionKeyOrOpenId(code);
        // 3.接收微信接口服务 获取返回的参数
        String openid = SessionKeyOpenId.getString("openid");
        String sessionKey = SessionKeyOpenId.getString("session_key");
        log.info("***************openid:"+openid);
        System.out.println(SessionKeyOpenId);
        //判断用户名和密码是否正确 如果正确继续向下执行
        SysUser userFind = iSysUserService.selectUserByUserName(username);
        if(userFind == null || StringUtils.isEmpty(userFind.getUserName())){
            log.info("*** the result of selectUserByUserName is wrong ");
            return result;
        }

        BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
        if(!encoder.matches(password, userFind.getPassword())){
            log.info("*** password is wrong ***");
            result = GlobalResult.build(401, "用户名或密码错误", "");
            return result;
        }

        //如果openId 为空,说明是第一次登陆, 将用户open_id,skey,session_key等信息存到数据库  如果openId不为空,更新最新登陆时间
        String openId = userFind.getOpenId();
        SysUser sysUser = new SysUser();
        // uuid生成唯一key,用于维护微信小程序用户与服务端的会话
        String skey = UUID.randomUUID().toString();
        if(StringUtils.isEmpty(openId)){

            sysUser.setOpenId(openid);
            sysUser.setSkey(skey+"");
            sysUser.setSessionKey(sessionKey+"");
            sysUser.setUserId(userFind.getUserId());
            iSysUserService.saveUserWxInfo(sysUser); //保存用户openId等信息
            //返回给小程序的用户信息补充
            userFind.setSkey(skey+"");
            userFind.setSessionKey(sessionKey);
        }else{
            if(!openId.equals(openid)){
                result = GlobalResult.build(HttpStatus.UNAUTHORIZED, "用户名或密码错误", userFind);
                return result;
            }
            //sysUser.setLoginDate();
            sysUser.setSkey(skey);  //是否需要更新到表里面

            //返回给小程序的用户信息补充
            userFind.setSkey(skey+"");    //是否需要更新到表里面  todo
        }
        //6. 把新的skey返回给小程序
        result = GlobalResult.build(HttpStatus.SUCCESS, "登录成功", userFind);
        return result;
    }
上一篇:Fastjson到了说再见的时候了


下一篇:SpringBoot整合原生OpenFegin的坑(非SpringCloud)