微信小程序后端

该代码段展示了如何实现微信小程序的登录和退出功能,包括使用账号密码登录、微信code2Session获取openid,以及用户信息的绑定和解绑。同时,通过拦截器实现了令牌的延迟过期管理,确保用户在有操作时保持登录状态。
摘要由CSDN通过智能技术生成

1.登陆退出


@Slf4j
//@RequestDecrypt
//@ResponseEncrypt
@RestController
@RequestMapping(value = "/applet")
@CrossOrigin
public class AppletLoginController {

    protected final Log logger = LogFactory.getLog(this.getClass());

    @Resource
    private ObjectMapper jacksonObjectMapper;
    @Resource
    private SecurityService securityService;
    @Resource
    private RedisTemplate<String, Object> redisTemplate;
    @Resource
    private Environment environment;
    @Resource
    private SysUserService sysUserService;

    //账号密码登录
    @PostMapping(value = "/login")
    public ReturnObject<Object> accountLogin(@RequestBody String _requestObj, HttpServletRequest request, HttpServletResponse response) throws Exception {
//        _requestObj = URLDecoder.decode(_requestObj,"UTF-8");
        Map<String, String> requestParams = jacksonObjectMapper.readValue(_requestObj, new TypeReference<Map<String, String>>() {
        });
        log.info("requestParams={}", requestParams);
        String loginName = requestParams.get("userName");
        String loginPass = requestParams.get("pwd");
        String code = requestParams.get("code");
        String appId = environment.getProperty("applet.appid");
        String appSecret = environment.getProperty("applet.appSecret");
        String grantType = environment.getProperty("applet.grant_type");
        String code2SessionUrl = environment.getProperty("applet.vx.code2Session");
        //根据code查是否存在已经绑定的用户
        //向微信服务器 使用登录凭证 code 获取 session_key 和 openid
        String params = "appid=" + appId + "&secret=" + appSecret + "&js_code=" + code + "&grant_type=" + grantType;
        String result = HttpRequest.sendGet(code2SessionUrl, params);
        Map<String, String> paramMap = jacksonObjectMapper.readValue(result, new TypeReference<Map<String, String>>() {
        });
        String errcode = paramMap.get("errcode");
        if (!ObjectUtils.isEmpty(errcode) && !"0".equals(errcode))
            return new ReturnObject<>(ConstantOfReturnCode.GLOBAL_RESULT_FALSE, "code有问题");
        String openId = paramMap.get("openid");
        if (ObjectUtils.isEmpty(loginName) && ObjectUtils.isEmpty(loginPass)) {
            String loginName1 = sysUserService.getUserAccountNameByOpenId(new SysUser().setOpenId(openId));
            //这个时候是第一次登录
            if (ObjectUtils.isEmpty(loginName1)) {
                return new ReturnObject<>(ConstantOfReturnCode.GLOBAL_RESULT_NO_BINDING, "未绑定微信");
            } else loginName = loginName1;
        } else {
            if (ObjectUtils.isEmpty(loginName))
                return new ReturnObject<>(ConstantOfReturnCode.GLOBAL_RESULT_FALSE, "请输入用户名!");
            if (ObjectUtils.isEmpty(loginPass))
                return new ReturnObject<>(ConstantOfReturnCode.GLOBAL_RESULT_FALSE, "请输入密码!");
            int i = sysUserService.setOpenIdByUserAccountName(new SysUser().setOpenId(openId).setUsername(loginName));
            if (i < 1) return new ReturnObject<>(ConstantOfReturnCode.GLOBAL_RESULT_FALSE, "绑定失败!");
        }

        User sysUser = securityService.retrieveSysUserByAccount(loginName);
        if (Objects.isNull(sysUser)) return new ReturnObject<>(ConstantOfReturnCode.GLOBAL_RESULT_FALSE, "用户不存在");
        if (sysUser.getState() != 1) return new ReturnObject<>(ConstantOfReturnCode.GLOBAL_RESULT_FALSE, "账号已停用");
        if (!ObjectUtils.isEmpty(loginName) && !ObjectUtils.isEmpty(loginPass) && !PasswordEncoderFactories.createDelegatingPasswordEncoder().matches(loginPass, sysUser.getPassword()))
            return new ReturnObject<>(ConstantOfReturnCode.GLOBAL_RESULT_FALSE, "密码错误");
        Map<Long, List<Role>> orgIdMapSysRoleList = securityService.getOrgIdWithRolesByUserId(sysUser.getId());
        if (orgIdMapSysRoleList.size() > 0) {
            Long id = orgIdMapSysRoleList.keySet().iterator().next();
            if (id == 0) {
                sysUser.setCurrentOrg(new Org().setId(0L).setName("").setState(1));
            } else {
                sysUser.setCurrentOrg(securityService.getOrgById(id));
            }
            sysUser.setOrgIdMapRoleList(orgIdMapSysRoleList);
        }
/*//        String authOfjson = jacksonObjectMapper.writeValueAsString(sysUser);
//        String subject = UUID.randomUUID().toString();
//        String authOfjwt = JWTHS256.buildJWT(subject, authOfjson);
//        response.addHeader("jwt", authOfjwt);
//        //跨域时允许header携带jwt
//        response.addHeader("Access-Control-Expose-Headers", "jwt");
//        redisTemplate.boundValueOps(SecurityConstants.getJwtKey(subject)).set("w", 60, TimeUnit.MINUTES);
//        response.setContentType("application/json;charset=utf-8");

//        return new ReturnObject<>(ConstantOfReturnCode.GLOBAL_RESULT_SUCESS, "", sysUser);*/
        String token = UUID.randomUUID().toString();
        try {
            redisTemplate.opsForValue().set(token, sysUser.getId(), 6, TimeUnit.HOURS);//改为1小时过期,有操作时会重置时间,保存userId
            redisTemplate.opsForValue().set(RedisKey.getUserKey(sysUser.getId()), jacksonObjectMapper.writeValueAsString(sysUser));
        } catch (JsonProcessingException e) {
            log.error(e.getMessage(), e);
            new ReturnObject<>(ConstantOfReturnCode.GLOBAL_RESULT_FALSE, "系统异常");
        }
        User user = new User().setUserId(sysUser.getId())
                .setName(sysUser.getName())
                .setUserName(sysUser.getUsername())
                .setRoles(sysUser.getOrgIdMapRoleList().values().iterator().next().stream().map(Role::getDesc).collect(Collectors.joining(",")));
        Map<String, Object> map = new HashMap<>();
        map.put("token", token);
        map.put("user", user);
        return new ReturnObject<>(ConstantOfReturnCode.GLOBAL_RESULT_SUCESS, "", map);
    }


    //账号密码退出-解除绑定微信
    @PostMapping(value = "/loginout")
    public ReturnObject<Object> loginout(@RequestBody String _requestObj, HttpServletRequest request, HttpServletResponse response) throws Exception {
        String token = request.getParameter("token");
        if (StringUtils.isNotBlank(token)) {
            Boolean isExp = redisTemplate.hasKey(token);
            if (Objects.nonNull(isExp) && isExp) {
                Object userId = redisTemplate.opsForValue().get(token);
                //删除token
                redisTemplate.delete(token);
                if (Objects.nonNull(userId)) {
                    //解除绑定
                    int i = sysUserService.setOpenIdNullByUserId(Long.parseLong(userId.toString()));
                    if (i > 0) return new ReturnObject<>(ConstantOfReturnCode.GLOBAL_RESULT_SUCESS, "退出成功!");
                }
            } else {
                Map<String, String> requestParams = jacksonObjectMapper.readValue(_requestObj, new TypeReference<Map<String, String>>() {
                });
                log.info("requestParams={}", requestParams);
                String userId = requestParams.get("userId");
                //解除绑定
                int i = sysUserService.setOpenIdNullByUserId(Long.parseLong(userId));
                if (i > 0) return new ReturnObject<>(ConstantOfReturnCode.GLOBAL_RESULT_SUCESS, "退出成功!");
            }
        }
        return new ReturnObject<>(ConstantOfReturnCode.GLOBAL_RESULT_FALSE, "退出失败!");
    }

    @Data
    @Accessors(chain = true)
    @JsonIgnoreProperties(ignoreUnknown = true)
    @JsonInclude(JsonInclude.Include.NON_EMPTY)
    static class User {
        private long userId;
        private String name;
        private String userName;
        private String roles;
    }

}

2.拦截器(token延时)


@Slf4j
public class AppletInterceptor implements HandlerInterceptor {

    private final RedisTemplate<String, Object> redisTemplate;
    private final ObjectMapper jacksonObjectMapper;

    public AppletInterceptor(ObjectMapper jacksonObjectMapper, RedisTemplate<String, Object> redisTemplate) {
        this.redisTemplate = redisTemplate;
        this.jacksonObjectMapper = jacksonObjectMapper;
    }

    protected final Log logger = LogFactory.getLog(this.getClass());

    @Override
    public boolean preHandle(@NonNull HttpServletRequest request,
                             @NonNull HttpServletResponse response,
                             @NonNull Object handler) {
/*        log.info("applet>>requestUrl:",request.getRequestURL());
        return true;
        String authenticationOfjwt = request.getHeader("jwt");
        if (StringUtils.isNotBlank(authenticationOfjwt)) {
            try {
                Map<String, Object> map = JWTHS256.vaildToken(authenticationOfjwt);
                if (Objects.nonNull(map) && map.size() == 2) {
                    String subject = (String) map.get("subject");
                    Boolean isExp = redisTemplate.hasKey(SecurityConstants.getJwtKey(subject));
                    if (Objects.nonNull(isExp) && isExp) {//redis key 未过期
                        redisTemplate.expire(SecurityConstants.getJwtKey(subject), 60, TimeUnit.MINUTES);//延期
                        String obj = (String) map.get("claim");
                        User sysUser = jacksonObjectMapper.readValue(obj, new TypeReference<User>() {
                        });
                        request.setAttribute("user", sysUser);
                        return true;
                    } else log.error("jwt数据过期");
                } else log.error("jwt数据非法");
            } catch (Exception e) {
                e.printStackTrace();
                logger.error(e.getLocalizedMessage());
            }
        } else {
            if (logger.isDebugEnabled()) {
                logger.debug("No JWT was available from the HttpServletRequestHeader!");
            }
        }*/
//        log.info("AppInterceptor>>preHandle(),requestURL={}",request.getRequestURL());
        String token = request.getParameter("token");
//        log.info("token={}", token);
        if (StringUtils.isNotBlank(token)) {
            Object userId = redisTemplate.opsForValue().get(token);
            //有操作时把token重置为1小时过期
            redisTemplate.opsForValue().set(token, userId, 6, TimeUnit.HOURS);//保存userId
            if (Objects.nonNull(userId)) {
                try {
                    Object json = redisTemplate.opsForValue().get(RedisKey.getUserKey(Long.parseLong(userId.toString())));
                    if (Objects.nonNull(json)) {
                        User user = jacksonObjectMapper.readValue(json.toString(), User.class);
                        request.setAttribute("user", user);
                        return true;
                    }
                } catch (JsonProcessingException e) {
                    log.error(e.getMessage(), e);
                }
            }
        }
        try {
            response.setStatus(200);
            response.setHeader("Content-Type", "text/plain;charset=utf-8");
            ReturnObject<Object> returnObject = new ReturnObject<>(ConstantOfReturnCode.GLOBAL_RESULT_FALSE, "用户未登陆");
            String result = jacksonObjectMapper.writeValueAsString(returnObject);
            response.getWriter().write(result);
        } catch (Exception e) {
            log.error(e.getMessage());
        }
        return false;
    }


    @Override
    public void postHandle(@NonNull HttpServletRequest request,
                           @NonNull HttpServletResponse response,
                           @NonNull Object handler, ModelAndView modelAndView) {
        //log.info("postHandle");
    }

    @Override
    public void afterCompletion(@NonNull HttpServletRequest request,
                                @NonNull HttpServletResponse response,
                                @NonNull Object handler, Exception ex) {
        //log.info("afterCompletion");
    }
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值