controller
@RestController
@RequestMapping("/login")
@Api(value = "管理API",tags = "用户登录")
@CrossOrigin
public class LoginController {
@Autowired
private IAdUserService adUserService;
@PostMapping("/in")
@ApiOperation(value = "用户登录" ,notes = "用户登录")
@ApiModelProperty(name ="dto" ,dataType = "LoginDto" ,required = true)
public ResponseResult login(@RequestBody LoginDto dto){
return adUserService.login(dto);
}
}
service
@Override
public ResponseResult login(LoginDto dto) {
// 先做判断:用户名和密码都不能为空
if( StringUtils.isBlank(dto.getName())||StringUtils.isBlank(dto.getPassword()) ) {
return ResponseResult.errorResult(AppHttpCodeEnum.NAME_PASSWORD_NOTNULL) ;
}
LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>();
// 先根据用户名查询
queryWrapper.eq(AdUser::getName,dto.getName());
AdUser one = this.getOne(queryWrapper);
if(one==null){
return ResponseResult.errorResult(AppHttpCodeEnum.USER_NOT_EXIST) ;
}
// 如果查询到用户后再比较密码
String password = one.getPassword();// c从表中获取的 是密文的
String password1 = dto.getPassword();//从页面来的 是明文的
// 把明文转成密文
password1 = DigestUtils.md5Hex(password1+one.getSalt());
if (!StringUtils.equals(password,password1)) {
return ResponseResult.errorResult(AppHttpCodeEnum.LOGIN_PASSWORD_ERROR) ;
}
// ================
Map resultMap = new HashMap();
one.setPassword("");
one.setSalt("");
one.setPhone("");
resultMap.put("user",one);
Map claimMaps = new HashMap<>();
claimMaps.put("userId",one.getId());
claimMaps.put("name",one.getName());
String token = AppJwtUtil.getToken(claimMaps);
resultMap.put("token",token);
return ResponseResult.okResult(resultMap);
}
说到底我们这里还是使用Filter进行配置,先整理一下思路再去选用工具类
@Component
public class AuthFilter implements GlobalFilter, Ordered {
@Override
public Mono filter(ServerWebExchange exchange, GatewayFilterChain chain) {
ServerHttpResponse response = exchange.getResponse();
ServerHttpRequest request = exchange.getRequest();
// 判断是否为登录操作 如果是登录操作直接放行
String path = request.getURI().getPath(); // api/v1/channel/list /login/in
if(path.contains("/login")){
return chain.filter(exchange); //直接放行
}
String token = request.getHeaders().getFirst("token");
// 判断请求头中是否携带token 如果没有直接返回401
if(StringUtils.isBlank(token)){
response.setStatusCode(HttpStatus.UNAUTHORIZED);
return response.setComplete();
}
// 如果携带token判断token是否有效
Claims claims = AppJwtUtil.getClaimsBody(token);
if(claims!=null){
// 如果有效从token中解析出userId和name放到请求头中继续进入到后面的微服务中
int type = AppJwtUtil.verifyToken(claims);
// -1:有效,0:有效
if(type==-1||type==0){
Integer userId = claims.get("userId", Integer.class);
String name = claims.get("name", String.class);
request.mutate().header("userId",userId.toString());
request.mutate().header("name",name);
return chain.filter(exchange); //放行
}
}
response.setStatusCode(HttpStatus.UNAUTHORIZED);
return response.setComplete();
}
@Override
public int getOrder() {
return 0;
}
}
public class AppJwtUtil {
// TOKEN的有效期一天(MS)
// private static final int TOKEN_TIME_OUT = 3600 * 1000 * 24;
private static final int TOKEN_TIME_OUT = 60 * 1000 ;
// 加密KEY
private static final String TOKEN_ENCRY_KEY = "MDk4ZjZiY2Q0NjIxZDM3M2NhZGU0ZTgzMjYyN2I0ZjY";
// 最小刷新间隔(S)
private static final int REFRESH_TIME = 300;
/**
* 生成token
*
* @param claimMaps 自定义信息
* @return
*/
public static String getToken(Map claimMaps) {
long currentTime = System.currentTimeMillis();
return Jwts.builder()
.setId(UUID.randomUUID().toString())
.setIssuedAt(new Date(currentTime)) //签发时间
.setSubject("system") //说明
.setIssuer("vhr") //签发者信息
.setAudience("app") //接收用户
.compressWith(CompressionCodecs.GZIP) //数据压缩方式
.signWith(SignatureAlgorithm.HS512, generalKey()) //加密方式
.setExpiration(new Date(currentTime + TOKEN_TIME_OUT)) //过期时间戳
.addClaims(claimMaps) //cla信息
.compact();
}
/**
* 获取token中的claims信息
*
* @param token
* @return
*/
private static Jws getJws(String token) {
return Jwts.parser()
.setSigningKey(generalKey())
.parseClaimsJws(token);
}
/**
* 获取payload body信息
*
* @param token
* @return
*/
public static Claims getClaimsBody(String token) {
try {
return getJws(token).getBody();
} catch (ExpiredJwtException e) {
return null;
}
}
/**
* 获取hearder body信息
*
* @param token
* @return
*/
public static JwsHeader getHeaderBody(String token) {
return getJws(token).getHeader();
}
/**
* 是否过期
*
* @param claims
* @return -1:有效,0:有效,1:过期,2:过期
*/
public static int verifyToken(Claims claims) {
if (claims == null) {
return 1;
}
try {
claims.getExpiration()
.before(new Date());
if ((claims.getExpiration().getTime() - System.currentTimeMillis()) > REFRESH_TIME * 1000) {
return -1;
} else {
return 0;
}
} catch (ExpiredJwtException ex) {
return 1;
} catch (Exception e) {
return 2;
}
}
/**
* 由字符串生成加密key
*
* @return
*/
public static SecretKey generalKey() {
byte[] encodedKey = Base64.getEncoder().encode(TOKEN_ENCRY_KEY.getBytes());
SecretKey key = new SecretKeySpec(encodedKey, 0, encodedKey.length, "AES");
return key;
}
public static void main(String[] args) {
// Map map = new HashMap();
// map.put("userId", "10001");
// map.put("userName", "tom");
// String token = AppJwtUtil.getToken(map);
// System.out.println(token);
String token ="NEdtwKL_ipswZnXIJoR3nQvdlAjI1GTrclTvV3szj2-R9XSEQsQ-lpS9JQQ00G6BdH2PDfFxmDT17xDj8XEzZll0LUvcFFROX5I_eA";
Jws jws = AppJwtUtil.getJws(token);
Claims claims = jws.getBody();
System.out.println(claims.get("userId"));
System.out.println(claims.get("userName"));
}
}