登陆controller:
package login;
import batch.User;
import com.alibaba.fastjson.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class LoginController {
@Autowired
User userMapper;
@Autowired
RedisServiceImpl redisService;
@RequestMapping("/login")
public String login(String username,String password){
//1.判断用户名密码是否正确
JSONObject userPO = userMapper.selectUserByName(username);
if (userPO == null) {
throw new RuntimeException("用户名不存在");
}
if (!password.equals(userPO.get("password"))) {
throw new RuntimeException("密码错误");
}
//2.用户名密码正确生成token
UserTokenDTO userTokenDTO = new UserTokenDTO();
userTokenDTO.setId((int)userPO.get("id"));
userTokenDTO.setCreateTime( System.currentTimeMillis());
String token = JWTUtil.generateToken(userTokenDTO);
//3.存入token至redis
redisService.set(userPO.get("id").toString(), token);
return token;
}
@RequestMapping("/loginOut")
public boolean loginOut(String id) {
boolean result = redisService.delete(id);
if (!redisService.delete(id)) {
throw new RuntimeException("退出登陆出错");
}
return result;
}
@RequestMapping("/updatePassword")
public String updatePassword(String id,String password) {
//1.修改密码
JSONObject user = userMapper.selectUserById(id);
if (user == null) {
throw new RuntimeException("用户不存在");
}
if (userMapper.updatePassword(id,password) != 1) {
throw new RuntimeException("密码更新失败");
}
//2.生成新的token
UserTokenDTO userTokenDTO = new UserTokenDTO();
userTokenDTO.setId(Integer.parseInt(id));
userTokenDTO.setCreateTime(System.currentTimeMillis());
userTokenDTO.setPhone(user.get("phone").toString());
String token = JWTUtil.generateToken(userTokenDTO);
//3.更新token
redisService.set(user.get("id").toString(), token);
return token;
}
}
UserTokenDTO:
package login;
public class UserTokenDTO {
private int id;
private String phone;
private long createTime;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
public Long getCreateTime() {
return createTime;
}
public void setCreateTime(long createTime) {
this.createTime = createTime;
}
}
JWTUtil:
package login;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.interfaces.DecodedJWT;
import java.util.HashMap;
import java.util.Map;
public class JWTUtil {
//私钥
private static final String TOKEN_SECRET = "123456";
/**
* 生成token,自定义过期时间 毫秒
*
* @param userTokenDTO
* @return
*/
public static String generateToken(UserTokenDTO userTokenDTO) {
try {
// 私钥和加密算法
Algorithm algorithm = Algorithm.HMAC256(TOKEN_SECRET);
// 设置头部信息
Map<String, Object> header = new HashMap<>(2);
header.put("Type", "Jwt");
header.put("alg", "HS256");
return JWT.create()
.withHeader(header)
.withClaim("token", JSONObject.toJSONString(userTokenDTO))
.sign(algorithm);
} catch (Exception e) {
System.out.println("generate token occur error");
return null;
}
}
/**
* 检验token是否正确
*
* @param token
* @return
*/
public static UserTokenDTO parseToken(String token) {
Algorithm algorithm = Algorithm.HMAC256(TOKEN_SECRET);
JWTVerifier verifier = JWT.require(algorithm).build();
DecodedJWT jwt = verifier.verify(token);
String tokenInfo = jwt.getClaim("token").asString();
return JSON.parseObject(tokenInfo, UserTokenDTO.class);
}
}
RedisServiceImpl(redis操作的封装类):
package login;
import javax.annotation.PostConstruct;
import javax.annotation.Resource;
public final class RedisServiceImpl {
/**
* 过期时长
*/
private final Long DURATION = 1 * 24 * 60 * 60 * 1000L;
@Resource
private RedisTemplate redisTemplate;
private ValueOperations<String, String> valueOperations;
@PostConstruct
public void init() {
RedisSerializer redisSerializer = new StringRedisSerializer();
redisTemplate.setKeySerializer(redisSerializer);
redisTemplate.setValueSerializer(redisSerializer);
redisTemplate.setHashKeySerializer(redisSerializer);
redisTemplate.setHashValueSerializer(redisSerializer);
valueOperations = redisTemplate.opsForValue();
}
public void set(String key, String value) {
valueOperations.set(key, value, DURATION, TimeUnit.MILLISECONDS);
log.info("key={}, value is: {} into redis cache", key, value);
}
public String get(String key) {
String redisValue = valueOperations.get(key);
log.info("get from redis, value is: {}", redisValue);
return redisValue;
}
public boolean delete(String key) {
boolean result = redisTemplate.delete(key);
log.info("delete from redis, key is: {}", key);
return result;
}
public Long getExpireTime(String key) {
return valueOperations.getOperations().getExpire(key);
}
}
TokenIntercept(拦截器,验证token是否需要续期):
package login;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.servlet.HandlerInterceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class TokenIntercept implements HandlerInterceptor {
@Autowired
RedisServiceImpl redisService;
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
String authToken = request.getHeader("Authorization");
String token = authToken.substring("Bearer".length() + 1).trim();
UserTokenDTO userTokenDTO = JWTUtil.parseToken(token);
//1.判断请求是否有效
if (redisService.get(String.valueOf(userTokenDTO.getId())) == null
|| !redisService.get(String.valueOf(userTokenDTO.getId())).equals(token)) {
return false;
}
//2.判断是否需要续期
if (redisService.getExpireTime(String.valueOf(userTokenDTO.getId())) < 1 * 60 * 30) {
redisService.set(String.valueOf(userTokenDTO.getId()), token);
System.out.println("update token info, id is:"+userTokenDTO.getId()+"user info is:"+token);
}
return true;
}
}
InterceptorConfig(拦截器配置类,登陆退出不需要走拦截器):
package login;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class InterceptorConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(TokenIntercept())
.excludePathPatterns("/logout/**")
.excludePathPatterns("/login/**")
.addPathPatterns("/**");
}
@Bean
public TokenIntercept TokenIntercept() {
return new TokenIntercept();
}
}