项目管理系统(springboot,springCloud,JWT,网关的使用)

后端: springboot+springcloud+jpa+redis+jwt
前端:vue

1.springCloud的使用
1.1:依赖

<parent>
       <groupId>org.springframework.boot</groupId>
       <artifactId>spring-boot-starter-parent</artifactId>
       <version>1.3.5.RELEASE</version>
       <relativePath /> <!-- lookup parent from repository -->
   </parent>

<dependencyManagement>
	<dependencies>
		<dependency>
			<groupId>org.springframework.cloud</groupId>
			<artifactId>spring-cloud-dependencies</artifactId>
			<version>Brixton.RELEASE</version>
			<type>pom</type>
			<scope>import</scope>
		</dependency>
	</dependencies>
</dependencyManagement>

<dependencies>
	<dependency>
		<groupId>org.springframework.cloud</groupId>
		<artifactId>spring-cloud-starter-config</artifactId>
	</dependency>
	<dependency>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-test</artifactId>
		<scope>test</scope>
	</dependency>
</dependencies>

<build>
	<plugins>
           <plugin>
               <groupId>org.springframework.boot</groupId>
               <artifactId>spring-boot-maven-plugin</artifactId>
           </plugin>
	</plugins>
</build>

   <!-- repositories also needed for snapshots and milestones -->

1.2:各个注解的功能

@EnableEurekaClient //开启eurka客户端
@EnableDiscoveryClient //发现feign客户端
@EnableFeignClients //开启feign客户端
@EnableZuulProxy //开启zuul代理

1.3: 跨服务调用:
在这里插入图片描述
熔断器相当于备用方案,实现client接口并重写其方法,具体使用详见官网(目前没用到,用到后补充)

2.网关的使用
2.1: 网关相当于入口,系统对外的唯一入口,用户所有的请求都会通过网关进入,因此网管最主要的功能有两个,
1.路由转发:接收一切外界请求,转发到后端的微服务上去。
2.过滤器:在服务网关中可以完成一系列的横切功能,例如权限校验、限流以及监控等,这些都可以通过过滤器完成(其实路由转发也是通过过滤器实现的。

例如鉴权,用户登录成功或发送一个jwt返回给前端,每次用户发送请求时携带该jwt,进入到网管后进行验证,若一直则可继续访问,不一致提示无法访问.
下面为zuulfilter的使用

public class WebFilter extends ZuulFilter {

    @Resource
    private RedisTemplate redisTemplate;




    @Override
    public String filterType() {
        return "pre";         //在微服务网关进行转发之前j进行过滤
    }

    @Override
    public int filterOrder() {
        return 0;  //数字越大,优先执行越低,0为最先执行
    }

    @Override
    public boolean shouldFilter() {
        RequestContext requestContext = RequestContext.getCurrentContext();
        HttpServletRequest request = requestContext.getRequest();
           //放行请求
        if (request.getRequestURL().indexOf("login") != -1){  //如果是登录请求,不使用过滤器
            return false;
        }
         
   




        return true;  //是否执行该过滤器
    }

    @Override
    public Object run() throws ZuulException {
         //前台网管需要吧用户的身份信息token转发给具体的微服务进行验证
        //而使用网关时是获取不到消息头的
        //需要在这个过滤器中,拿到用户信息
        RequestContext currentContext = RequestContext.getCurrentContext();

        //获取用户原来的请求
        HttpServletRequest request = currentContext.getRequest();

        //获取y用户信息
        String header = request.getHeader("Authorization");
        String token = header.substring(7);
            //获取用户id
        String userHeader = request.getHeader("userId");


        //进行校验
        if (!token.equals(redisTemplate.boundValueOps(userHeader).get())){
                //读取的token和该用户生成的token不同,token无效
            System.out.println("非法token");
        }





        //转发token,转发到后端的微服务时同时也需要带上token。
        currentContext.addZuulRequestHeader("Authorization",header);




        return null;

    }
}

网关的配置:
在这里插入图片描述

3.jwt鉴权
3.1 在用户登陆成功后需要生成jwt,用于鉴别用户身份.
当用户通过发请求的方式访问到后端时,会优先通过网关,同时发请求的过程中是携带token进行验证的.
然而还有一种情况,就是用户发请求后,后端的微服务之间的互相进行调用,在后端自行调用的过程中用户是没有发送第二次请求的,因此也不会有token,再次进入到网关时会鉴权失败.
解决方法:
流程: 用户 —> 微服务A —>调用微服务B
1.在微服务A 中自定义拦截器 实现AccessDecisionManager,HandlerInterceptor
重写 decide(Authentication authentication, Object object, Collection configAttributes)方法(具体执行如下)

@Override
	public void decide(Authentication authentication, Object object, Collection<ConfigAttribute> configAttributes)
			throws AccessDeniedException, InsufficientAuthenticationException {
		// TODO Auto-generated method stub
		if(object instanceof FilterInvocation) {
			FilterInvocation invocation = (FilterInvocation)object;

			HttpServletRequest request = invocation.getHttpRequest();

			String header = request.getHeader("Authorization");

			//2. 判断获取到的值是否为空
			if (header == null || "".equals(header)) {
				throw new AccessDeniedException("");
			}

			//3. 判断获取到的值是否合法,判断是否以Bearer + 空格开头
			if (!header.startsWith("Bearer ")) {
				throw new AccessDeniedException("");
			}

			//4. 获取token的值,进行解析,使用jwtutil工具类进行解析
			String token = header.substring(7);
			System.out.println("token为: "+token);
			try {
				Claims claims = jwtUtil.parseJWT(token);

				//5.判断解析的claims是否为空
				if (claims == null) {
					throw new AccessDeniedException("");
				}

				System.out.println(claims.get("roles"));
                request.setAttribute("claims",claims);
                request.setAttribute("token",token);
				return;
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		
		throw new AccessDeniedException("");
	}

这个其实很简单,微服务A是用户发请求的,自然是有请求头的,在A服务中获取请求头,然后将token解析出来,claims是在JwtUtil中定义的,为解析完token后的对象,可通过claims.get(“roles”)获取用户信息

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值