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");
}
}