1.添加pom
<!--shiro-->
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
<version>1.3.2</version>
</dependency>
<dependency>
<groupId>org.crazycake</groupId>
<artifactId>shiro-redis</artifactId>
<version>2.4.2.1-RELEASE</version>
<exclusions>
<exclusion>
<artifactId>shiro-core</artifactId>
<groupId>org.apache.shiro</groupId>
</exclusion>
</exclusions>
</dependency>
2.自定义Reaml授权认证验证器
import com.ph.bean.UpmsPermission;
import com.ph.bean.UpmsRole;
import com.ph.bean.UpmsUser;
import com.ph.exception.AppException;
import com.ph.manager.service.UpmsRoleService;
import com.ph.manager.service.UpmsUserService;
import com.ph.util.ApiResult;
import com.ph.util.ResultEnum;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.PrincipalCollection;
import org.springframework.beans.factory.annotation.Autowired;
import java.util.ArrayList;
import java.util.List;
/**
* @Author xiongxiaopeng
* @Description 自定义授权认证验证器-手机号加密码登录
* @Date 2020/12/17 9:03
* @Version 1.0
*/
@Slf4j
public class AuthRealm extends AuthorizingRealm {
@Autowired
private UpmsRoleService upmsRoleService;
@Autowired
private UpmsUserService upmsUserService;
/**
* @desc shiro用户授权
* @param principalCollection
* @return org.apache.shiro.authz.AuthorizationInfo
* @date 2020/12/17 9:54
* @author xiongxiaopeng
*/
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
String phone = principalCollection.getPrimaryPrincipal().toString();
ApiResult<UpmsUser> userApiResult=upmsUserService.findUserByPhone(phone);
UpmsUser upmsUser=userApiResult.getData();
UpmsRole upmsRole=upmsUserService.findUpmsRoleByUserId(upmsUser.getId());
List<UpmsPermission> upmsPermissionList=upmsUserService.findUserPermissionByUserId(upmsUser.getId());
List<String> userPermission = new ArrayList<>();
for(UpmsPermission upmsPermission:upmsPermissionList){
userPermission.add(upmsPermission.getUri());
}
authorizationInfo.addRole(upmsRole.getId());
authorizationInfo.addStringPermissions(userPermission);
return authorizationInfo;
}
/**
* @desc 认证,登录时调用subject.login()方法时触发
* @param authenticationToken
* @return org.apache.shiro.authc.AuthenticationInfo
* @date 2020/12/17 9:55
* @author xiongxiaopeng
*/
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) {
UsernamePasswordToken token = (UsernamePasswordToken) authenticationToken;
String phone=token.getUsername();
ApiResult<UpmsUser> userApiResult=upmsUserService.findUserByPhone(phone);
UpmsUser upmsUser=userApiResult.getData();
if(upmsUser==null){
throw new AppException(ResultEnum.MANAGER_NOT_UPMS_USER);
}
if (upmsUser.getLocked() == 1) {
throw new AppException(ResultEnum.MANAGER_UPMS_USER_LOCK);
}
AuthenticationInfo authInfo = new SimpleAuthenticationInfo(phone, upmsUser.getPassword(), this.getName());
//清之前的授权信息
super.clearCachedAuthorizationInfo(authInfo.getPrincipals());
//登录信息放进session中
Session session = SecurityUtils.getSubject().getSession();
session.setAttribute(ShiroContent.SESSION_NAME, upmsUser);
return authInfo;
}
}
3.创建ShiroConfig.java,把CustomRealm和SecurityManager 、SessionManager、ExceptionHandler等注入到spring容器中:
import com.ph.bean.UpmsPermission;
import com.ph.manager.service.UpmsRoleService;
import com.ph.manager.service.UpmsUserService;
import org.apache.shiro.authc.Authenticator;
import org.apache.shiro.authc.pam.ModularRealmAuthenticator;
import org.apache.shiro.authz.Authorizer;
import org.apache.shiro.authz.ModularRealmAuthorizer;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.realm.Realm;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.apache.shiro.web.session.mgt.DefaultWebSessionManager;
import org.crazycake.shiro.RedisCacheManager;
import org.crazycake.shiro.RedisManager;
import org.crazycake.shiro.RedisSessionDAO;
import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.HandlerExceptionResolver;
import javax.servlet.Filter;
import java.util.*;
/**
* @Author xiongxiaopeng
* @Description shiro控制管理
* @Date 2020/12/17 10:07
* @Version 1.0
*/
@Configuration
public class ShiroConfig {
@Autowired
private UpmsRoleService upmsRoleService;
@Autowired
private UpmsUserService upmsUserService;
@Value("${spring.redis.host}")
private String host;
@Value("${spring.redis.port}")
private int port;
@Value("${spring.redis.password}")
private String password;
/**
* 各种地址拦截
*/
@Bean
public ShiroFilterFactoryBean shirFilter(SecurityManager securityManager) {
List<UpmsPermission> permissionList=this.upmsUserService.selectAllUpmsPermission();
//安全管理器
ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
shiroFilterFactoryBean.setSecurityManager(securityManager);
// URL拦截
Map<String, String> filterChainDefinitionMap = new LinkedHashMap<String, String>();
// 配置不会被拦截的链接(静态文件,登录页面等)顺序判断
filterChainDefinitionMap.put("/manager/verificationCodeGenerate", "anon");
filterChainDefinitionMap.put("/manager/backPasswordCodeGenerate", "anon");
filterChainDefinitionMap.put("/manager/backPassword", "anon");
filterChainDefinitionMap.put("/manager/smsCOde", "anon");
filterChainDefinitionMap.put("/manager/login", "anon");
filterChainDefinitionMap.put("/manager/operation/*", "anon");
filterChainDefinitionMap.put("/manager/operationAppLog", "anon");
filterChainDefinitionMap.put("/manager/operationMerLog", "anon");
for (UpmsPermission permission : permissionList) {
if (permission.getType() != 1) {
filterChainDefinitionMap.put(permission.getUri(), "perms[" + permission.getUri() + "]");
}
}
//退出登录连接
filterChainDefinitionMap.put("/manager/updatePwd", "authc");
//filterChainDefinitionMap.put("/manager/logout", "logout");
// 过滤链定义,从上向下顺序执行,一般将 /**放在最为下边
filterChainDefinitionMap.put("/**", "corsAuthenticationFilter");
shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
//自定义过滤器
Map<String, Filter> filterMap = new LinkedHashMap<>();
filterMap.put("corsAuthenticationFilter", corsAuthenticationFilter());
shiroFilterFactoryBean.setFilters(filterMap);
return shiroFilterFactoryBean;
}
/**
* 注入安全管理器
*/
@Bean
public SecurityManager securityManager() {
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
// 自定义缓存实现 使用redis
//securityManager.setCacheManager(cacheManager());
// 自定义session管理 使用redis
securityManager.setSessionManager(sessionManager());
设置realm
AuthRealm realm = authRealm();
securityManager.setAuthorizer(authorizer(realm));
securityManager.setAuthenticator(authenticator(realm));
securityManager.setRealm(authRealm());
return securityManager;
}
/**
* 注入自定义的shiro授权验证类
*/
@Bean
public AuthRealm authRealm() {
AuthRealm authRealm = new AuthRealm();
authRealm.setCredentialsMatcher(credentialsMatcher());
return authRealm;
}
@Bean
public Authorizer authorizer(AuthRealm myRealm) {
ModularRealmAuthorizer authorizer = new ModularRealmAuthorizer();
Collection<Realm> crealms = new ArrayList<>();
crealms.add(myRealm);
authorizer.setRealms(crealms);
return authorizer;
}
@Bean
public Authenticator authenticator(AuthRealm myRealm) {
ModularRealmAuthenticator authenticator = new ModularRealmAuthenticator();
Collection<Realm> crealms = new ArrayList<>();
crealms.add(myRealm);
authenticator.setRealms(crealms);
return authenticator;
}
/**
* 开启shiro aop注解支持.
* 使用代理方式;所以需要开启代码支持;
*
* @param securityManager
* @return
*/
@Bean
public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager) {
AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
authorizationAttributeSourceAdvisor.setSecurityManager(securityManager);
return authorizationAttributeSourceAdvisor;
}
/**
* 注入自定义的密码加密校验类
*/
@Bean
public CustomCredentialsMatcher credentialsMatcher() {
return new CustomCredentialsMatcher();
}
/**
* 配置shiro redisManager
* 使用的是shiro-redis开源插件
*
* @return
*/
public RedisManager redisManager() {
RedisManager redisManager = new RedisManager();
redisManager.setHost(host);
redisManager.setPort(port);
redisManager.setExpire(1800);// 配置缓存过期时间
//redisManager.setTimeout(timeout);
redisManager.setPassword(password);
return redisManager;
}
/**
* cacheManager 缓存 redis实现
* 使用的是shiro-redis开源插件
*
* @return
*/
public RedisCacheManager cacheManager() {
RedisCacheManager redisCacheManager = new RedisCacheManager();
redisCacheManager.setRedisManager(redisManager());
return redisCacheManager;
}
/**
* RedisSessionDAO shiro sessionDao层的实现 通过redis
* 使用的是shiro-redis开源插件
*/
@Bean
public RedisSessionDAO redisSessionDAO() {
RedisSessionDAO redisSessionDAO = new RedisSessionDAO();
redisSessionDAO.setRedisManager(redisManager());
return redisSessionDAO;
}
/**
* shiro session的管理
*/
@Bean
public DefaultWebSessionManager sessionManager() {
MySessionManager sessionManager = new MySessionManager();
sessionManager.setSessionDAO(redisSessionDAO());
sessionManager.setGlobalSessionTimeout(ShiroContent.MANAGER_SESSION_TIMEOUT*60*1000);
return sessionManager;
}
public CorsAuthenticationFilter corsAuthenticationFilter() {
return new CorsAuthenticationFilter();
}
//自动创建代理,没有这个鉴权可能会出错
@Bean
public DefaultAdvisorAutoProxyCreator getDefaultAdvisorAutoProxyCreator() {
DefaultAdvisorAutoProxyCreator autoProxyCreator = new DefaultAdvisorAutoProxyCreator();
autoProxyCreator.setProxyTargetClass(true);
return autoProxyCreator;
}
/**
* 注册全局异常处理
*
* @return
*/
@Bean(name = "exceptionHandler")
public HandlerExceptionResolver handlerExceptionResolver() {
return new MyExceptionHandler();
}
}
Cors跨域过滤器
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;
/**
* @program: wallet
* @description: 每次请求返回报文中添加报文头
**/
@Configuration
public class CorsConfig {
private CorsConfiguration buildConfig() {
CorsConfiguration corsConfiguration = new CorsConfiguration();
corsConfiguration.addAllowedOrigin("*"); // 1 设置访问源地址
corsConfiguration.addAllowedHeader("*"); // 2 设置访问源请求头
corsConfiguration.addAllowedMethod("*"); // 3 设置访问源请求方法
return corsConfiguration;
}
@Bean
public CorsFilter corsFilter() {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", buildConfig()); // 4 对接口配置跨域设置
return new CorsFilter(source);
}
}
mport com.alibaba.fastjson.JSONObject;
import com.ph.util.ResultEnum;
import org.apache.shiro.web.filter.authc.FormAuthenticationFilter;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.OutputStream;
import java.io.PrintWriter;
public class CorsAuthenticationFilter extends FormAuthenticationFilter {
public CorsAuthenticationFilter() {
super();
}
@Override
protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) {
if (request instanceof HttpServletRequest) {
if (((HttpServletRequest) request).getMethod().toUpperCase().equals("OPTIONS")) {
return true;
}
}
return super.isAccessAllowed(request, response, mappedValue);
}
@Override
protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception {
HttpServletResponse res = (HttpServletResponse) response;
res.setHeader("Access-Control-Allow-Origin", "*");
res.setStatus(HttpServletResponse.SC_OK);
res.setCharacterEncoding("UTF-8");
res.setContentType("application/json; charset=utf-8");
PrintWriter writer = res.getWriter();
JSONObject jsonObject = new JSONObject();
jsonObject.put("code", ResultEnum.TOKEN_ERROR.getCode());
jsonObject.put("msg", ResultEnum.TOKEN_ERROR.getMsg());
writer.write(jsonObject.toJSONString());
writer.flush();
writer.close();
return false;
}
}
自定义的密码加密校验类
import com.ph.util.md5.MD5Util;
import lombok.SneakyThrows;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authc.credential.SimpleCredentialsMatcher;
/**
* @Author xiongxiaopeng
* @Description 自定义的密码加密校验器
* @Date 2020/12/17 10:33
* @Version 1.0
*/
public class CustomCredentialsMatcher extends SimpleCredentialsMatcher {
@SneakyThrows
@Override
public boolean doCredentialsMatch(AuthenticationToken token, AuthenticationInfo info) {
UsernamePasswordToken usertoken = (UsernamePasswordToken) token;
//注意token.getPassword()拿到的是一个char[],不能直接用toString(),它底层实现不是我们想的直接字符串,只能强转
Object tokenCredentials = MD5Util.MD5(String.valueOf(usertoken.getPassword()));
//获取登录用户的密码
Object accountCredentials = getCredentials(info);
//将密码加密与系统加密后的密码校验,内容一致就返回true,不一致就返回false
return equals(tokenCredentials, accountCredentials);
}
}
自定义异常处理类 ExceptionHandler
import com.alibaba.fastjson.support.spring.FastJsonJsonView;
import com.ph.util.ResultEnum;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.authz.UnauthenticatedException;
import org.apache.shiro.authz.UnauthorizedException;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.servlet.HandlerExceptionResolver;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.HashMap;
import java.util.Map;
@Slf4j
@Component
@ControllerAdvice
public class MyExceptionHandler implements HandlerExceptionResolver {
@Override
public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
ModelAndView mv = new ModelAndView();
FastJsonJsonView view = new FastJsonJsonView();
Map<String, Object> attributes = new HashMap<String, Object>();
if (ex instanceof UnauthenticatedException) {
attributes.put("code", ResultEnum.MANAGER_USER_PASSWORD_ERROR.getCode());
attributes.put("msg", ResultEnum.MANAGER_USER_PASSWORD_ERROR.getMsg());
ex.printStackTrace();
} else if (ex instanceof UnauthorizedException) {
attributes.put("code", ResultEnum.SAFETY_PERMISSION_ERROR.getCode());
attributes.put("msg", ResultEnum.SAFETY_PERMISSION_ERROR.getMsg());
ex.printStackTrace();
} else {
ex.printStackTrace();
attributes.put("code", "1000003");
attributes.put("msg", ex.getMessage());
}
view.setAttributesMap(attributes);
mv.setView(view);
return mv;
}
}
自定义SessionManager
import com.ph.util.md5.MD5Util;
import lombok.SneakyThrows;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.web.session.mgt.DefaultWebSessionManager;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import java.io.Serializable;
public class MySessionManager extends DefaultWebSessionManager {
@Autowired
private StringRedisTemplate stringRedisTemplate;
public MySessionManager() {
super();
}
@SneakyThrows
@Override
protected Serializable getSessionId(ServletRequest request, ServletResponse response) {
HttpServletRequest req = (HttpServletRequest) request;
String token = req.getHeader("token");//header方式
//如果请求头中有 Authorization 则其值为sessionId
if (StringUtils.isNotEmpty(token)) {
String userId = (String) stringRedisTemplate.opsForValue().get(token);
if(StringUtils.isBlank(userId)){
return null;
}
String userSessionIdKey = ShiroContent.MANAGER_USER_SESSION_ID + MD5Util.MD5(MD5Util.MD5(userId));
return (String) stringRedisTemplate.opsForValue().get(userSessionIdKey);
} else {
//否则按默认规则从cookie取sessionId
return super.getSessionId(request, response);
}
}
}
shiro相关常量
public interface ShiroContent {
String SESSION_NAME="MANAGER_USER_SESSION_NAME";
String MANAGER_USER_SESSION_ID="sea_manager_upms:user_session_id_";
String MANAGER_COLL_VERIFICATION_CODE="sea_manager_login:verification_code_";
String MANAGER_SMS_VERIFICATION_CODE="sea_manager_login:verification_code_";
String MANAGER_USER_TOKEN="sea_manager:upmsuser_token_";
String MANAGER_USER_INFO="sea_manager:upmsuser_info_";
String MANAGER_USER_ONLINE="sea_manager:upmsuser_online_";
//session超时设置,单位分钟
long MANAGER_SESSION_TIMEOUT=120;
}
登录、退出
import com.alibaba.fastjson.JSON;
import com.ph.bean.UpmsPermission;
import com.ph.bean.UpmsRole;
import com.ph.bean.UpmsUser;
import com.ph.bean.vo.manager.*;
import com.ph.enums.sms.SmsCodeTypeEnum;
import com.ph.manager.service.UpmsRoleService;
import com.ph.manager.service.UpmsUserService;
import com.ph.manager.shiro.ShiroContent;
import com.ph.util.ApiResult;
import com.ph.util.ResultEnum;
import com.ph.util.check.SmsCodeCheckUtil;
import com.ph.util.md5.MD5Util;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
/**
* @Description 登录相关
*/
@Slf4j
@RestController
@RequestMapping("/manager")
public class ManagerLoginController {
@Autowired
private UpmsRoleService upmsRoleService;
@Autowired
private UpmsUserService upmsUserService;
@Autowired
private StringRedisTemplate stringRedisTemplate;
/**
* @desc 用户登录
* @param loginReqVo
* @return com.ph.util.ApiResult<com.ph.bean.vo.manager.LoginRespVo>
* @date 2020/12/17 12:34
* @author xiongxiaopeng
*/
@PostMapping(value = "/login")
public ApiResult<LoginRespVo> login(@RequestBody @Valid LoginReqVo loginReqVo) throws Exception{
String key = ShiroContent.MANAGER_COLL_VERIFICATION_CODE+loginReqVo.getPhone();
String sessionCode = stringRedisTemplate.opsForValue().get(key);
stringRedisTemplate.delete(key);
//判断验证码是否相等
if(!loginReqVo.getCode().equalsIgnoreCase(sessionCode)){
return ApiResult.fail(ResultEnum.MANAGER_LOGIN_CODE_ERROR);
}
//判断用户是否存在
UpmsUser upmsUser =upmsUserService.findUserByPhone(loginReqVo.getPhone()).getData();
if(upmsUser==null){
return ApiResult.fail(ResultEnum.MANAGER_USER_PASSWORD_ERROR);
}
UpmsRole upmsRole=upmsUserService.findUpmsRoleByUserId(upmsUser.getId());
if(upmsRole==null||upmsRole.getRoleState()==0){
return ApiResult.fail(ResultEnum.MANAGER_USER_PASSWORD_ERROR);
}
Subject subject = SecurityUtils.getSubject();
UsernamePasswordToken token = new UsernamePasswordToken(loginReqVo.getPhone(), loginReqVo.getPassword());
subject.login(token);
String sessionId = (String) subject.getSession().getId();
List<UpmsPermission> upmsPermissionList=upmsUserService.findUserPermissionByUserId(upmsUser.getId());
List<String> userPermission = new ArrayList<>();
for(UpmsPermission upmsPermission:upmsPermissionList){
userPermission.add(upmsPermission.getUri());
}
String userToken = ShiroContent.MANAGER_USER_TOKEN + MD5Util.MD5(MD5Util.MD5(upmsUser.getId() + UUID.randomUUID().toString()));
String userInfo=ShiroContent.MANAGER_USER_INFO + MD5Util.MD5(MD5Util.MD5(upmsUser.getId()));
String userSessionIdKey = ShiroContent.MANAGER_USER_SESSION_ID + MD5Util.MD5(MD5Util.MD5(upmsUser.getId()));
String jsonString = JSON.toJSONString(upmsUser);
String userOnlineKey = ShiroContent.MANAGER_USER_ONLINE + MD5Util.MD5(MD5Util.MD5(upmsUser.getId()));
String s = stringRedisTemplate.opsForValue().get(userOnlineKey);
if (StringUtils.isNotEmpty(s)){
stringRedisTemplate.delete(s);
}
stringRedisTemplate.opsForValue().set(userToken, upmsUser.getId(), ShiroContent.MANAGER_SESSION_TIMEOUT, TimeUnit.MINUTES);
stringRedisTemplate.opsForValue().set(userInfo, jsonString, ShiroContent.MANAGER_SESSION_TIMEOUT, TimeUnit.MINUTES);
stringRedisTemplate.opsForValue().set(userOnlineKey, userToken, ShiroContent.MANAGER_SESSION_TIMEOUT, TimeUnit.MINUTES);
stringRedisTemplate.opsForValue().set(userSessionIdKey, sessionId, ShiroContent.MANAGER_SESSION_TIMEOUT, TimeUnit.MINUTES);
LoginRespVo loginRespVo=new LoginRespVo();
loginRespVo.setRealName(upmsUser.getRealName());
loginRespVo.setUserToken(userToken);
loginRespVo.setUserPermissions(userPermission);
return ApiResult.success(loginRespVo);
}
/**
* @desc 退出登录
* @param token
* @return com.ph.util.ApiResult
* @date 2020/12/17 14:00
* @author xiongxiaopeng
*/
@PostMapping(value = "/logout")
public ApiResult loginOut(@RequestBody @Valid LoginOutVo token)throws Exception{
String userId= stringRedisTemplate.opsForValue().get(token.getToken());
Subject subject = SecurityUtils.getSubject();
subject.logout();
if(StringUtils.isNotBlank(userId)) {
String userOnlineKey = ShiroContent.MANAGER_USER_ONLINE + MD5Util.MD5(MD5Util.MD5(userId));
String userInfo = ShiroContent.MANAGER_USER_INFO + MD5Util.MD5(MD5Util.MD5(userId));
String userSessionIdKey = ShiroContent.MANAGER_USER_SESSION_ID + MD5Util.MD5(MD5Util.MD5(userId));
stringRedisTemplate.delete(Arrays.asList(token.getToken(), userInfo, userSessionIdKey, userOnlineKey));
}
return ApiResult.success();
}
/**
* @desc 找回密码
* @return com.ph.util.ApiResult
* @date 2020/12/17 14:00
* @author xiongxiaopeng
*/
@PostMapping(value = "/backPassword")
public ApiResult backPassword(@RequestBody @Valid ForgetPasswordReqVo forgetPasswordReqVo){
if (!SmsCodeCheckUtil.isValidSmsCode(stringRedisTemplate, SmsCodeTypeEnum.MANAGER_BACK_PASSWORD, forgetPasswordReqVo.getPhone(),forgetPasswordReqVo.getCode(), Boolean.TRUE))
{
return ApiResult.fail(ResultEnum.MANAGER_LOGIN_CODE_ERROR);
}
UpmsUser upmsUser =upmsUserService.findUserByPhone(forgetPasswordReqVo.getPhone()).getData();
if(upmsUser==null){
return ApiResult.fail(ResultEnum.MANAGER_NOT_UPMS_USER);
}
if(!forgetPasswordReqVo.getNewPassword().equals(forgetPasswordReqVo.getConfirmPassword())){
return ApiResult.fail(ResultEnum.PASSWORD_COMPARISON_ERROR);
}
return upmsUserService.updatePassword(upmsUser.getId(),forgetPasswordReqVo.getNewPassword());
}
/**
* @desc 修改密码
* @param passwordReqVo
* @return com.ph.util.ApiResult
* @date 2020/12/25 20:00
* @author xiongxiaopeng
*/
@PostMapping(value = "/updatePwd")
public ApiResult updatePwd(@RequestBody @Valid PasswordReqVo passwordReqVo)throws Exception{
String userId= stringRedisTemplate.opsForValue().get(passwordReqVo.getToken());
if(StringUtils.isBlank(userId)){
return ApiResult.fail(ResultEnum.TOKEN_ERROR);
}
if(!passwordReqVo.getNewPassword().equals(passwordReqVo.getConfirmPassword())){
return ApiResult.fail(ResultEnum.PASSWORD_COMPARISON_ERROR);
}
ApiResult<UpmsUser> upmsUser =upmsUserService.findUserById(userId);
if(upmsUser==null || upmsUser.getData()==null){
return ApiResult.fail(ResultEnum.DATE_NULL);
}
if(!upmsUser.getData().getPassword().equals(MD5Util.MD5(passwordReqVo.getOldPassword()))) {
return ApiResult.fail(ResultEnum.PASSWORD_ORIGINAL_ERROR);
}
return upmsUserService.updatePassword(upmsUser.getData().getId(),passwordReqVo.getNewPassword());
}
}
session中获取用户信息
Session session = SecurityUtils.getSubject().getSession();
UpmsUser upmsUser=(UpmsUser)session.getAttribute(ShiroContent.SESSION_NAME);