Loading

认证服务对接网关

 新建网关工程changgou_gateway_web

1) changgou_gateway添加依赖

 <!--网关依赖-->
    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-gateway</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
        <!--redis-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis-reactive</artifactId>
            <version>2.1.3.RELEASE</version>
        </dependency>
    </dependencies>

2) 新建工程changgou_gateway_web,并创建启动类

@SpringBootApplication
@EnableDiscoveryClient
public class WebGateWayApplication {
​
    public static void main(String[] args) {
        SpringApplication.run(WebGateWayApplication.class,args);
    }
}

3) 创建application.yml

spring:
  application:
    name: gateway-web
  cloud:
    gateway:
      globalcors:
        cors-configurations:
          '[/**]': # 匹配所有请求
            allowedOrigins: "*" #跨域处理 允许所有的域
            allowedMethods: # 支持的方法
              - GET
              - POST
              - PUT
              - DELETE
      routes:
        - id: changgou_goods_route
          uri: lb://goods
          predicates:
            - Path=/api/album/**,/api/brand/**,/api/cache/**,/api/categoryBrand/**,/api/category/**,/api/para/**,/api/pref/**,/api/sku/**,/api/spec/**,/api/spu/**,/api/stockBack/**,/api/template/**
          filters:
            #- PrefixPath=/brand
            - StripPrefix=1
          #用户微服务
        - id: changgou_user_route
          uri: lb://user
          predicates:
            - Path=/api/user/**,/api/address/**,/api/areas/**,/api/cities/**,/api/provinces/**
          filters:
            - StripPrefix=1
          #认证微服务
        - id: changgou_oauth_user
          uri: lb://user-auth
          predicates:
            - Path=/api/oauth/**
          filters:
            - StripPrefix=1
  redis:
    host: 192.168.200.128
server:
  port: 8001
eureka:
  client:
    service-url:
      defaultZone: http://127.0.0.1:6868/eureka
  instance:
    prefer-ip-address: true
management:
  endpoint:
    gateway:
      enabled: true
    web:
      exposure:
        include: true

 网关全局过滤器

新建过滤器类AuthorizeFilter,对请求进行过滤

业务逻辑:

1)判断当前请求是否为登录请求,是的话,则放行

2) 判断cookie中是否存在信息, 没有的话,拒绝访问

3)判断redis中令牌是否存在,没有的话,拒绝访问

@Component
public class AuthFilter implements GlobalFilter, Ordered {
​
    public static final String Authorization = "Authorization";
​
    @Autowired
    private AuthService authService;
​
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
​
        //获取当前请求对象
        ServerHttpRequest request = exchange.getRequest();
        ServerHttpResponse response = exchange.getResponse();
​
        String path = request.getURI().getPath();
        if ("/api/oauth/login".equals(path)){
            //放行
            return chain.filter(exchange);
        }
​
        //判断cookie上是否存在jti
        String jti = authService.getJtiFromCookie(request);
        if (StringUtils.isEmpty(jti)){
            //拒绝访问,请求跳转
            response.setStatusCode(HttpStatus.UNAUTHORIZED);
            return response.setComplete();
        }
​
​
        //判断redis中token是否存在
        String redisToken = authService.getTokenFromRedis(jti);
        if (StringUtils.isEmpty(redisToken)){
            //拒绝访问,请求跳转
            response.setStatusCode(HttpStatus.UNAUTHORIZED);
            return response.setComplete();
        }
​
        //校验通过 , 请求头增强,放行
        request.mutate().header(Authorization,"Bearer "+redisToken);
        return chain.filter(exchange);
    }
​
    @Override
    public int getOrder() {
        return 0;
    }
}

新建业务逻辑类AuthService

@Service
public class AuthService {
​
    @Autowired
    private StringRedisTemplate stringRedisTemplate;
​
    /**
     * 判断cookie中jti是否存在
     * @param request
     * @return
     */
    public String getJtiFromCookie(ServerHttpRequest request) {
        HttpCookie cookie = request.getCookies().getFirst("uid");
        if (cookie!=null){
            return cookie.getValue();
        }
        return null;
    }
​
    /**
     * 判断redis中令牌是否过期
     * @param jti
     * @return
     */
    public String getTokenFromRedis(String jti) {
        String token = stringRedisTemplate.boundValueOps(jti).get();
        return token;
    }
}

测试:

清除postman中的cookie数据,在未登录的情况下,并访问: http://localhost:8001/api/user 。会返回401异常信息

访问:http://localhost:8001/api/oauth/login,并重新测试。可以发现测试通过,拿到返回结果数据

自定义登录页面

认证服务添加依赖

<!--thymeleaf-->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>

资源\成品页面\登录页面

把页面放到下面的项目中

静态资源放行

修改WebSecurityConfig类

web.ignoring().antMatchers(
                "/oauth/login",
                "/oauth/logout","/oauth/toLogin","/login.html","/css/**","/data/**","/fonts/**","/img/**","/js/**");

添加开启表单登录

LoginRedirectController

@Controller
@RequestMapping("/oauth")
public class LoginRedirectController {
​
    @RequestMapping("/toLogin")
    public String toLogin(){
        return "login";
    }
}

修改登录页面实现用户登录

定义login方法

<script th:inline="javascript">
    var app = new Vue({
        el:"#app",
        data:{
            username:"",
            password:"",
            msg:""
        },
        methods:{
            login:function(){
                app.msg="正在登录";
                axios.post("/api/oauth/login?username="+app.username+"&password="+app.password).then(function (response) {
                    if (response.data.flag){
                        app.msg="登录成功";
                    }else{
                        app.msg="登录失败";
                    }
                })
            }
        }
    })
</script>

定义路径过滤

public class URLFilter {
​
    public static String filterPath = "/api/wseckillorder,/api/seckill,/api/wxpay,/api/wxpay/**,/api/worder/**,/api/user/**,/api/address/**,/api/wcart/**,/api/cart/**,/api/categoryReport/**,/api/orderConfig/**,/api/order/**,/api/orderItem/**,/api/orderLog/**,/api/preferential/**,/api/returnCause/**,/api/returnOrder/**,/api/returnOrderItem/**";
​
    public static boolean hasAuthorize(String url){
​
        String[] split = filterPath.replace("**", "").split(",");
​
        for (String value : split) {
​
            if (url.startsWith(value)){
                return true;
            }
        }
​
        return false;
    }
}

测试

访问:http://localhost:9200/oauth/toLogin

posted @ 2021-08-10 13:20  1640808365  阅读(215)  评论(0编辑  收藏  举报