用户鉴权处理

目录

思路分析

会话保持

步骤


思路分析

1.用户通过访问微服务网关调用微服务,同时携带头文件信息

2.在微服务网关这里进行拦截,拦截后获取用户要访问的路径

3.识别用户访问的路径是否需要登录,如果需要,识别用户的身份是否能访问该路径[这里可以基于数据库设计一套权限]

4.如果需要权限访问,用户已经登录,则放行

5.如果需要权限访问,且用户未登录,则提示用户需要登录

6.用户通过网关访问用户微服务,进行登录验证

7.验证通过后,用户微服务会颁发一个令牌给网关,网关会将用户信息封装到头文件中,并响应用户

8.用户下次访问,携带头文件中的令牌信息即可识别是否登录

会话保持

用户每次请求的时候,我们都需要获取令牌数据,方法有多重,可以在每次提交的时候,将数据提交到头文件中,也可以将数据存储到Cookie中,每次从Cookie中校验数据,还可以每次将令牌数据以参数的方式提交到网关,这里面采用Cookie的方式比较容易实现。

步骤

  • 登录封装Cookie

    /***    *用户登录    */   
    @RequestMapping(value = "/login")   
    public Result login(String username, String password, HttpServletResponse response){     
    //查询用户信息     
    User user = userService.findByUsername(username);
    
        if(user!=null && BCrypt.checkpw(password,user.getPassword())){
    
            //设置令牌信息       
            Map<String,Object> info=new HashMap<>();       
            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 cookie = new Cookie("Authorization",jwt);       
            //设置cookie的路径           
            cookie.setPath("/");       
            //把cookie使用响应头设置给浏览器       
            response.addCookie(cookie);        
    
            return new Result(true,StatusCode.OK,"登录成功!",jwt);     
        }     
        return new Result(false,StatusCode.LOGINERROR,"账号或者密码错误!");   
    }
    • 修改user微服务,每次登录的时候,添加令牌信息到Cookie中,修改dongyimai-user-service的com.offcn.user.controller.UserControllerlogin方法

  • 过滤器获取令牌数据

    package xin.yi.filter;

    import io.jsonwebtoken.Claims; 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; import xin.yi.utils.JwtUtil;

    /**

    • @program: dongyimai-parent

    • @description:

    • @author: xin yi

    • @create: 2021-08-14 21:24 */ @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) { /设置Request、Response对象*/ ServerHttpRequest request = exchange.getRequest(); ServerHttpResponse response = exchange.getResponse();

        /获取请求的URI/ String path = request.getURI().getPath();

        /**

        • 如果是登录、goods等开放的微服务[这里的goods部分开放],则直接放行,这里不做完整演示,完整演示需要设计一套权限系统 / if (path.startsWith("/api/user/login") || path.startsWith("/api/brand/search/")){ /放行*/ Mono<Void> filter = chain.filter(exchange); return filter; }

        /获取头文件中的令牌信息/ String tokent = request.getHeaders().getFirst(AUTHORIZE_TOKEN);

        /**

        • 如果头文件中没有,则从请求参数中获取 */ if (StringUtils.isEmpty(tokent)){ tokent = request.getQueryParams().getFirst(AUTHORIZE_TOKEN); }

        /**
         * 从cookie中获取令牌数据
         */
        HttpCookie first = request.getCookies().getFirst(AUTHORIZE_TOKEN);
        if (null != first){
            tokent = first.getValue();
        }
    ​
        /**
         * 如果为空,则输出错误代码
         */
        if (StringUtils.isEmpty(tokent)){
            /*设置方法不允许被访问,405错误代码*/
            response.setStatusCode(HttpStatus.METHOD_NOT_ALLOWED);
            return response.setComplete();
        }
    ​
        /**
         * 解析令牌数据
         */
        try {
            Claims claims = JwtUtil.parseJWT(tokent);
            /*在令牌信息校验那块将令牌加入到请求头中*/
            request.mutate().header(AUTHORIZE_TOKEN,claims.toString());
        } catch (Exception e) {
            e.printStackTrace();
            /*解析失败响应401错误*/
            response.setStatusCode(HttpStatus.UNAUTHORIZED);
            return response.setComplete();
        }
    ​
        /*放行*/
        return chain.filter(exchange);
    }
    /**
     * 过滤器执行顺序
     * @return
     */
    @Override
    public int getOrder() {
        return 0;
    }

    }

    • 每次在网关中通过过滤器获取Cookie中的令牌,然后对令牌数据进行解析,修改微服务网关dongyimai-gateway-web中的AuthorizeFilter

  • 添加Header信息

    Claims claims = JwtUtil.parseJWT(token); //把解析出来的令牌添加到头文件中 request.mutate().header(AUTHORIZE_TOKEN,claims.toString());

    • 我们还可以在Gateway的全局过滤器中添加请求头信息,例如可以将令牌信息添加到请求头中,在微服务中获取头信息

      //获取请求头中封装的令牌     String token = request.getHeader("Authorization");     System.out.println("令牌信息:"+token);

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

xinyi_java

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值