从零开始创建微服务-OAuth2-day9

12 用户认证与网关整合

  1. 所有请求都会经过服务网关,服务网关对外暴露服务,在网关进行统一用户认证,然后网关再下发至服务;

在这里插入图片描述

  1. 既然要在网关进行用户认证,网关得知道对那些url进行认证,所以需要对url进行规则制定;

  2. api接口是异步请求的,我们采取url规则进行匹配,如/api/*/auth/*,凡是满足该规则的用户都需要进行认证。

12.1 调整service-gateway模块

在service-gateway模块中新建filter包,创建AuthGlobalFilter类

@Component
public class AuthGlobalFilter implements GlobalFilter, Ordered {

    private AntPathMatcher antPathMatcher = new AntPathMatcher();

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        ServerHttpRequest request = exchange.getRequest();
        String path = request.getURI().getPath();
        System.out.println("==="+path);

        //内部服务接口,不允许外部访问
        if(antPathMatcher.match("/**/inner/**", path)) {
            ServerHttpResponse response = exchange.getResponse();
            return out(response, ResultCodeEnum.PERMISSION);
        }

//        Long userId = this.getUserId(request);


        //api接口,异步请求,校验用户必须登录
        if(antPathMatcher.match("/api/**/auth/**", path)) {
            Long userId = this.getUserId(request);
            if(StringUtils.isEmpty(userId)) {
                ServerHttpResponse response = exchange.getResponse();
                return out(response, ResultCodeEnum.LOGIN_AUTH);
            }
        }
        return chain.filter(exchange);
    }

    @Override
    public int getOrder() {
        return 0;
    }

    /**
     * api接口鉴权失败返回数据
     * @param response
     * @return
     */
    private Mono<Void> out(ServerHttpResponse response, ResultCodeEnum resultCodeEnum) {
        Result result = Result.build(null, resultCodeEnum);
        byte[] bits = JSONObject.toJSONString(result).getBytes(StandardCharsets.UTF_8);
        DataBuffer buffer = response.bufferFactory().wrap(bits);
        //指定编码,否则在浏览器中会中文乱码
        response.getHeaders().add("Content-Type", "application/json;charset=UTF-8");
        return response.writeWith(Mono.just(buffer));
    }

    /**
     * 获取当前登录用户id
     * @param request
     * @return
     */
    private Long getUserId(ServerHttpRequest request) {
        String token = "";
        List<String> tokenList = request.getHeaders().get("token");
        //token不为空,直接获取token
        if(null  != tokenList) {
            token = tokenList.get(0);
        }
        //如果token为空,则直接返回这个值
        if(!StringUtils.isEmpty(token)) {
            return JwtHelper.getUserId(token);
        }
        return null;
    }
}

前端的utils/request.js中添加

// http request 拦截器
service.interceptors.request.use(
  config => {
    //判断cookie是否有token值
    if (cookie.get("token")) {
      //token值放到cookie里面
      config.headers["token"] = cookie.get("token");
    }
    return config;
  },
  err => {
    return Promise.reject(err);
  }
);

13 OAuth2开放授权

OAuth2主要解决一些特定问题,

  • 开放系统间授权问题
  • 单点登录问题

OAuth(开放授权)是一个开放标准,只约定解决方案,不约定具体怎么做,允许用户授权第三方移动应用访问他们存储在另外的服务提供者上的信息,而不需要将用户名和密码提供给第三方移动应用或分享他们数据的所有内容。有关OAuth2的用法:https://blog.csdn.net/finalheart/article/details/103102828(作者:finalheart),

https://blog.csdn.net/weixin_34080571/article/details/91715402(标题:基于spring-security-oauth2实现oauth2 作者:JhonXie)

13.1 OAuth2应用场景

  • 第三方应用授权登录:在APP或者网页接入一些第三方应用时,时长会需要用户登录另一个合作平台,比如QQ,微博,微信的授权登录。
  • 原生app授权:app登录请求后台接口,为了安全认证,所有请求都带token信息,如果登录验证、请求后台数据。
  • 前后端分离单页面应用(spa):前后端分离框架,前端请求后台数据,需要进行oauth2安全认证,比如使用vue、react后者h5开发的app。

13.2 OAuth2用法

其实oauth就是一个流程。我们根据这个流程的要求写代码。流程如下图所示:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3xpIEdLT-1640678445170)(C:\Users\1234\AppData\Roaming\Typora\typora-user-images\image-20211227193323755.png)]

A. 用户打开客户端以后,客户端要求用户给予授权

B.用户同意给予客户端授权

c.客户端使用上一步获得的授权,向认证服务器申请令牌

d.认证服务器对客户端进行认证以后,确认无误,同意发放令牌

e.客户端使用令牌,向资源服务器申请获取资源

f.资源服务器确认令牌无误,同意向客户端开放资源

oauth有一个授权服务器。是作为用户的认证用的。对于服务端来说只需实现一个oauth的授权服务器。对于用户来说(调用授权认证的研发)只需根据流程发请求就可以了。

13.3 OAuth2的四种方式

OAuth2是为了不把密码暴露给第三方

1.授权码 authorization code 也是安全等级最高的一版。 支持refresh token 一般都用这个,微博QQ登录就是这种方式。

2.密码 password credentials 支持refresh token 这种安全等级低。

3.简化模式 implicit 不支持refresh token 这种没有获取code的步骤。

4.客户端模式 client credentials 不支持refresh token 这种是被信任的内部client使用。一般内部平台间使用

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值