登陆成功后,将token保存到redis
@RestController
public class LoginController {
@Autowired
private StringRedisTemplate stringRedisTemplate;
@GetMapping("doLogin")
public String doLogin(String username, String password){
System.out.println("username = " + username);
System.out.println("password = " + password);
//考虑用validation
if(!StringUtils.hasLength(username)||!StringUtils.hasLength(password)){
return "用户名或密码不能为空";
}
User user = new User(1, username, password);
String token = UUID.randomUUID().toString();
stringRedisTemplate.opsForValue().set(token,user.toString(), Duration.ofHours(2));
//登陆本质就是返回token
return token;
}
}
在网关过滤器中验证token
@Component
public class TokenCheckFilter implements GlobalFilter, Ordered {
/**
* 放行的uri
*/
private static final List<String> ALLOW_RUI;
static {
ALLOW_RUI = new ArrayList<>();
ALLOW_RUI.add("/login-service/doLogin");
ALLOW_RUI.add("/doLogin");
}
@Autowired
private StringRedisTemplate stringRedisTemplate;
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
ServerHttpRequest request = exchange.getRequest();
String path = request.getURI().getPath();
// 放行
if (ALLOW_RUI.contains(path)) {
return chain.filter(exchange);
}
//校验token
List<String> authorization = request.getHeaders().get("Authorization");
if (!CollectionUtils.isEmpty(authorization)) {
String token = authorization.get(0);
if (StringUtils.hasText(token)) {
//约定规范 bearer token
//bearer考虑用常量替换
String realToken = token.replaceFirst("bearer ", "");
//真实token不为空并且redis中存在该token
if (StringUtils.hasText(realToken) && stringRedisTemplate.hasKey(realToken)) {
// 放行
return chain.filter(exchange);
}
}
}
//拦截
ServerHttpResponse response = exchange.getResponse();
response.getHeaders().set("content-type", "application/json;charset=utf-8");
Map<String, Object> map = new HashMap<>(4);
// 401 未授权
map.put("code", HttpStatus.UNAUTHORIZED.value());
map.put("msg", HttpStatus.UNAUTHORIZED.getReasonPhrase());
ObjectMapper objectMapper = new ObjectMapper();
byte[] bytes = new byte[0];
try {
bytes = objectMapper.writeValueAsBytes(map);
} catch (JsonProcessingException e) {
e.printStackTrace();
}
DataBuffer dataBuffer = response.bufferFactory().wrap(bytes);
return response.writeWith(Mono.just(dataBuffer));
}
@Override
public int getOrder() {
return 1;
}
}
在访问其他接口时,都需要在请求头中加入Authorization=bearer token