1. JWT测试
public class JwtTest {
@Test
public void testCreateJwt() {
JwtBuilder builder = Jwts.builder()
.setId("8989")
.setIssuer("csp1999")
.setSubject("JWT加密测试")
.setIssuedAt(new Date())
.setExpiration(new Date(System.currentTimeMillis() + 1000 * 60 * 3));
Map<String,Object> userInfo = new HashMap<>();
userInfo.put("username","csp");
userInfo.put("password","123456");
userInfo.put("school","河南科技大学");
userInfo.put("age","22");
builder.addClaims(userInfo);
builder.signWith(SignatureAlgorithm.HS256, "haust");
String jwtStr = builder.compact();
System.out.println(jwtStr);
}
@Test
public void testParseJwt() {
String jwtStr = "eyJhbGciOiJIUzI1NiJ9.eyJqdGkiOiI4OTg5IiwiaXNzIjoiY3NwMTk5OSIsInN1YiI6IkpXVOWKoOWvhua1i-ivlSIsImlhdCI6MTYxMTQ4ODc1MSwiZXhwIjoxNjExNDg4OTMxLCJwYXNzd29yZCI6IjEyMzQ1NiIsInNjaG9vbCI6Iuays-WNl-enkeaKgOWkp-WtpiIsImFnZSI6IjIyIiwidXNlcm5hbWUiOiJjc3AifQ.uH28G9MSHfzaKBAOyr8AdksYLVvy8O5P8g7TORZIUFY";
Claims claims = Jwts.parser().
setSigningKey("haust").
parseClaimsJws(jwtStr).
getBody();
System.out.println(claims);
}
}
2. JWT工具类
public class JwtUtil {
public static final Long JWT_TTL = 3600000L;
public static final String JWT_KEY = "itcast";
public static String createJWT(String id, String subject, Long ttlMillis) {
SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;
long nowMillis = System.currentTimeMillis();
Date now = new Date(nowMillis);
if (ttlMillis == null) {
ttlMillis = JwtUtil.JWT_TTL;
}
long expMillis = nowMillis + ttlMillis;
Date expDate = new Date(expMillis);
SecretKey secretKey = generalKey();
JwtBuilder builder = Jwts.builder()
.setId(id)
.setSubject(subject)
.setIssuer("admin")
.setIssuedAt(now)
.signWith(signatureAlgorithm, secretKey)
.setExpiration(expDate);
return builder.compact();
}
public static SecretKey generalKey() {
byte[] encodedKey = Base64.getEncoder().encode(JwtUtil.JWT_KEY.getBytes());
SecretKey key = new SecretKeySpec(encodedKey, 0, encodedKey.length, "AES");
return key;
}
public static Claims parseJWT(String jwt) throws Exception {
SecretKey secretKey = generalKey();
return Jwts.parser()
.setSigningKey(secretKey)
.parseClaimsJws(jwt)
.getBody();
}
public static void main(String[] args) {
String jwt = JwtUtil.createJWT("weiyibiaoshi", "aaaaaa", null);
System.out.println(jwt);
try {
Claims claims = JwtUtil.parseJWT(jwt);
System.out.println(claims);
} catch (Exception e) {
e.printStackTrace();
}
}
}
3. 用户登录校验
3.1 网关过滤器
@Component
public class AuthorizeFilter implements GlobalFilter, Ordered {
private static final String AUTHORIZE_TOKEN = "Authorization";
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
ServerHttpRequest request = exchange.getRequest();
ServerHttpResponse response = exchange.getResponse();
String path = request.getURI().getPath();
if (path.startsWith("/api/user/login") || path.startsWith("/api/brand/search/")) {
Mono<Void> filter = chain.filter(exchange);
return filter;
}
String token = request.getHeaders().getFirst(AUTHORIZE_TOKEN);
boolean hasToken = true;
if (StringUtils.isEmpty(token)) {
token = request.getQueryParams().getFirst(AUTHORIZE_TOKEN);
hasToken = false;
}
if (StringUtils.isEmpty(token)) {
response.setStatusCode(HttpStatus.METHOD_NOT_ALLOWED);
return response.setComplete();
}
try {
Claims claims = JwtUtil.parseJWT(token);
} catch (Exception e) {
e.printStackTrace();
response.setStatusCode(HttpStatus.UNAUTHORIZED);
return response.setComplete();
}
request.mutate().header(AUTHORIZE_TOKEN,token);
return chain.filter(exchange);
}
@Override
public int getOrder() {
return 0;
}
}
3.2 网关微服务application.yml
spring:
cloud:
gateway:
globalcors:
corsConfigurations:
'[/**]':
allowedOrigins: "*"
allowedMethods:
- GET
- POST
- PUT
- DELETE
routes:
- id: changgou_goods_route
uri: lb://changgou-goods
predicates:
- Path=/api/brand/**,/api/category/**
filters:
- StripPrefix=1
- name: RequestRateLimiter
args:
key-resolver: "#{@ipKeyResolver}"
redis-rate-limiter.replenishRate: 1
redis-rate-limiter.burstCapacity: 1
- id: changgou_user_route
uri: lb://changgou-user
predicates:
- Path=/api/user/**,/api/address/**,/api/areas/**,/api/cities/**,/api/provinces/**
filters:
- StripPrefix=1
application:
name: changgou-gateway-web
redis:
database: 0
host: 8.131.66.136
port: 6379
password: csp19990129
server:
port: 8001
eureka:
client:
service-url:
defaultZone: http://127.0.0.1:7001/eureka
instance:
prefer-ip-address: true
management:
endpoint:
gateway:
enabled: true
web:
exposure:
include: true
3.3 网关微服务主启动类
@SpringBootApplication
@EnableEurekaClient
public class GatewayWebApplication {
public static void main(String[] args) {
SpringApplication.run(GatewayWebApplication.class, args);
}
@Bean(name = "ipKeyResolver")
public KeyResolver userKeyResolver() {
return new KeyResolver() {
@Override
public Mono<String> resolve(ServerWebExchange exchange) {
String hostName = exchange.getRequest().getRemoteAddress().getAddress().getHostAddress();
System.out.println("hostName:" + hostName);
return Mono.just(hostName);
}
};
}
}
3.4 用户微服务编写登录代码
@RestController
@RequestMapping("/user")
@CrossOrigin
public class UserController {
@Autowired
private UserService userService;
@PutMapping(value = "/{id}")
public Result update(@RequestBody User user, @PathVariable String id) {
...
}
@PostMapping
public Result add(@RequestBody User user) {
...
}
@GetMapping("/{id}")
public Result<User> findById(@PathVariable String id) {
...
}
@GetMapping
public Result<List<User>> findAll() {
...
}
@RequestMapping("/login")
public Result<User> login(String username, String password, HttpServletResponse response, HttpServletRequest request) {
User user = userService.findById(username);
if (user == null) {
return new Result<User>(false, StatusCode.LOGINERROR, "用户名或密码错误...");
}
if (BCrypt.checkpw(password, user.getPassword())) {
Map<String, Object> info = new HashMap<String, Object>();
info.put("role", "USER");
info.put("success", "SUCCESS");
info.put("username", username);
String jwt = JwtUtil.createJWT(UUID.randomUUID().toString(), JSON.toJSONString(info), null);
Cookie cookie = new Cookie("Authorization", jwt);
response.addCookie(cookie);
response.setHeader("Authorization", jwt);
return new Result<User>(true, StatusCode.OK, "登录成功", jwt);
} else {
return new Result<User>(false, StatusCode.LOGINERROR, "用户名或密码错误");
}
}
}