微服务-网关-全局过滤器鉴权(未使用spring security)
请求访问微服务通过网关的进行鉴权的类
jwt : https://www.cnblogs.com/Jomini/p/14163713.html
import com.jm.util.JwtUtil; import org.springframework.cloud.gateway.filter.GatewayFilterChain; import org.springframework.cloud.gateway.filter.GlobalFilter; import org.springframework.core.Ordered; import org.springframework.http.HttpCookie; import org.springframework.http.HttpStatus; import org.springframework.http.server.reactive.ServerHttpRequest; import org.springframework.http.server.reactive.ServerHttpResponse; import org.springframework.stereotype.Component; import org.springframework.util.StringUtils; import org.springframework.web.server.ServerWebExchange; import reactor.core.publisher.Mono; @Component public class AuthorizeFilter implements GlobalFilter, Ordered { //令牌头名字 private static final String AUTHORIZE_TOKEN = "Authorization"; /** * 全局拦截 * @param exchange * @param chain * @return */ @Override public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) { ServerHttpRequest request = exchange.getRequest(); ServerHttpResponse response = exchange.getResponse(); //获取用户令牌信息,如果没有令牌,则拦截 // 1、参数获取令牌 String token = request.getHeaders().getFirst(AUTHORIZE_TOKEN); //boolean true : 令牌在头文件中 false:令牌不在头文件中 boolean hasToken = true; // 2、头文件中获取 if(StringUtils.isEmpty(token)){ token = request.getQueryParams().getFirst(AUTHORIZE_TOKEN); hasToken = false; } // 3、Cookie中 if(StringUtils.isEmpty(token)){ HttpCookie httpCookie = request.getCookies().getFirst(AUTHORIZE_TOKEN); if(httpCookie != null){ token = httpCookie.getValue(); } } //如果没有令牌,返回无效响应 if(StringUtils.isEmpty(token)){ //设置没有权限的状态码 401 response.setStatusCode(HttpStatus.UNAUTHORIZED); // 响应空数据 return response.setComplete(); } //如果有令牌, 则校验令牌是否有效 try { JwtUtil.parseJWT(token); } catch (Exception e) { //无效拦截 //设置没有权限的状态码 401 response.setStatusCode(HttpStatus.UNAUTHORIZED); // 响应空数据 return response.setComplete(); } //将令牌封装到头文件中 request.mutate().header(AUTHORIZE_TOKEN, token); //有效则放行 return chain.filter(exchange); } @Override public int getOrder() { return 0; } }
用户登录代码
@RequestMapping(value = "/login") public Result login(String username,String password, HttpServletResponse response, HttpServletRequest request){ //查询用户信息 User user = userService.findById(username); if(BCrypt.checkpw(password, user.getPassword())){ //创建用户令牌信息 Map<String,Object> tokenMap = new HashMap<String,Object>(); tokenMap.put("role","USER"); tokenMap.put("success","SUCCESS"); tokenMap.put("username",username); //设置令牌信息 String token = JwtUtil.createJWT(UUID.randomUUID().toString(), JSON.toJSONString(tokenMap), null); //把令牌存入到Cookie Cookie cookie = new Cookie("Authorization", token); cookie.setDomain("localhost"); cookie.setPath("/"); response.addCookie(cookie); //把令牌作为参数给用户 //密码匹配, 登录成功 return new Result(true, StatusCode.OK, "登录成功!",token); } if(user!=null && BCrypt.checkpw(password,user.getPassword())){ return new Result(true,StatusCode.OK,"登录成功!",user); } return new Result(false,StatusCode.LOGINERROR,"账号或者密码错误!"); }
只有先访问用户登录,获取到 jwt 再携带 jwt 直接访问