1.配置白名单
#自定义内容
sc:
jwt:
secret: sc@Login(Auth}*^31)&czxy% # 登录校验的密钥(自定义内容)
pubKeyPath: D:/rsa/rsa.pub # 公钥地址
priKeyPath: D:/rsa/rsa.pri # 私钥地址
expire: 360 # 过期时间,单位分钟
filter:
allowPaths:
- /user/login
- /user/checkUsername
- /user/register
- /classes
2.获得白名单
package com.czxy.config;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import java.util.List;
@Data
@ConfigurationProperties(prefix = "sc.filter")
public class FilterProperties {
private List<String> allowPaths;
}
3.拷贝JwtProperties
4.编写过滤器
package com.czxy.filter;
import com.czxy.config.FilterProperties;
import com.czxy.config.JwtProperties;
import com.czxy.domain.User;
import com.czxy.utils.JwtUtils;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import javax.annotation.Resource;
import java.nio.charset.StandardCharsets;
import java.util.List;
/**
* @author 桐叔
* @email liangtong@itcast.cn
* @description
*/
@Component
@EnableConfigurationProperties({FilterProperties.class})
public class LoginFilter implements GlobalFilter, Ordered {
@Resource
private FilterProperties filterProperties;
@Resource
private JwtProperties jwtProperties;
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
//1 获得请求路径
String path = exchange.getRequest().getURI().getPath();
System.out.println(path);
//2 白名单
List<String> allowPathList = filterProperties.getAllowPaths();
for(String allowPath : allowPathList) {
// 请求路径中,包含放行的路径
if(path.contains(allowPath)) {
return chain.filter(exchange);
}
}
//3 校验token
//3.1 获得token Authorization
String token = exchange.getRequest().getHeaders().getFirst("Authorization");
try {
//3.2 校验token,解析成功
JwtUtils.getObjectFromToken(token, jwtProperties.getPublicKey(), User.class);
// 放行
return chain.filter(exchange);
} catch (Exception e) {
//3.3 处理失败结果
ServerHttpResponse response = exchange.getResponse();
response.setStatusCode(HttpStatus.UNAUTHORIZED); //401
response.getHeaders().add("Content-Type","application/json;charset=UTF-8");
DataBuffer wrap = response.bufferFactory().wrap("没有权限".getBytes(StandardCharsets.UTF_8));
return exchange.getResponse().writeWith(Flux.just(wrap));
}
}
@Override
public int getOrder() {
return 1;
}
}
5.校验失败前端处理
//导入element ui message
import { MessageBox } from 'element-ui'
export default function ({ $axios, redirect }) {
//请求前执行(请求拦截器)
$axios.onRequest(config => {
//获得token
let token = localStorage.getItem('token')
//携带token
$axios.setToken(token)
})
//Ajax请求失败时执行
$axios.onError(error => {
// 获得状态码
const code = parseInt(error.response && error.response.status)
// 如果状态码为400,重定向到“/400”页面
if (code === 400) {
redirect('/400')
}
// 如果状态码为401,提示没有权限,并跳转到登录页面
if(code === 401) {
//删除无效token (可省略)
localStorage.removeItem('token')
//提示
MessageBox.confirm(error.response.data, '提示', {
confirmButtonText: '重新登录',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
//确定,跳转到登录
location.href = '/user/login'
}).catch(() => {
//取消
});
}
})
}