整合營銷服務(wù)商

          電腦端+手機(jī)端+微信端=數(shù)據(jù)同步管理

          免費(fèi)咨詢熱線:

          單點(diǎn)登錄總結(jié)(共享cookie、傳統(tǒng)SSO、JWT、Gateway)

          1.共享cookie實(shí)現(xiàn)單點(diǎn)登錄

          1.1 單系統(tǒng)登錄的解決方案是cookie,cookie攜帶會(huì)話id在瀏覽器與服務(wù)器之間維護(hù)會(huì)話狀態(tài)。但是cookie是有限制的,這個(gè)限制就是cookie的域(通常對(duì)應(yīng)網(wǎng)站的域名),瀏覽器發(fā)送http請(qǐng)求時(shí)會(huì)自動(dòng)攜帶與該域匹配的cookie,而不是所有cookie。

          1.2 共享cookie的方式存在眾多局限:

          1)首先,應(yīng)用群域名得統(tǒng)一;

          2)應(yīng)用群各系統(tǒng)使用的技術(shù)(至少是web服務(wù)器)要相同,不然cookie的key變量(tomcat為)不同,無法維持會(huì)話,共享cookie的方式是無法實(shí)現(xiàn)跨語言技術(shù)平臺(tái)登錄的,比如java、php、.net系統(tǒng)之間;

          cookie本身不安全。

          2.單點(diǎn)登錄SSO

          2.1 什么是單點(diǎn)登錄:

          單點(diǎn)登錄全稱Single Sign On(以下簡稱SSO),是指在多系統(tǒng)應(yīng)用群中登錄一個(gè)系統(tǒng),便可在其他所有系統(tǒng)中得到授權(quán)而無需再次登錄,包括單點(diǎn)登錄與單點(diǎn)注銷兩部分

          2.2 sso登錄流程:

          sso需要一個(gè)獨(dú)立的認(rèn)證中心,只有認(rèn)證中心能接受用戶的用戶名密碼等安全信息。sso認(rèn)證中心驗(yàn)證用戶的用戶名密碼沒問題,創(chuàng)建授權(quán)令牌,在接下來的跳轉(zhuǎn)過程中,授權(quán)令牌作為參數(shù)發(fā)送給各個(gè)子系統(tǒng),子系統(tǒng)拿到令牌,即得到了授權(quán),可以借此創(chuàng)建局部會(huì)話,局部會(huì)話登錄方式與單系統(tǒng)的登錄方式相同

          2.3 sso注銷流程

          單點(diǎn)登錄自然也要單點(diǎn)注銷,在一個(gè)子系統(tǒng)中注銷,所有子系統(tǒng)的會(huì)話都將被銷毀

          用戶向系統(tǒng)1發(fā)起注銷請(qǐng)求
          系統(tǒng)1根據(jù)用戶與系統(tǒng)1建立的會(huì)話id拿到令牌,向sso認(rèn)證中心發(fā)起注銷請(qǐng)求
          sso認(rèn)證中心校驗(yàn)令牌有效,銷毀全局會(huì)話,同時(shí)取出所有用此令牌注冊(cè)的系統(tǒng)地址
          sso認(rèn)證中心向所有注冊(cè)系統(tǒng)發(fā)起注銷請(qǐng)求
          各注冊(cè)系統(tǒng)接收sso認(rèn)證中心的注銷請(qǐng)求,銷毀局部會(huì)話
          sso認(rèn)證中心引導(dǎo)用戶至登錄頁面
          

          3.JWT單點(diǎn)登錄

          以上的session還有token的方案,在集群環(huán)境下,都是靠第三方緩存數(shù)據(jù)庫redis來實(shí)現(xiàn)數(shù)據(jù)的共享。

          跟以上那些唯一的不同點(diǎn)就是:token存放了用戶的基本信息,更直觀一點(diǎn)就是將原本放入redis中的用戶數(shù)據(jù),放入到token中去了!

          JWT相比session方案,因?yàn)閖son的通用性,所以JWT是可以進(jìn)行跨語言支持的,像JAVA、、PHP等很多語言都可以使用,而session方案只針對(duì)JAVA。

          因?yàn)橛辛藀ayload部分,所以JWT可以存儲(chǔ)一些其他業(yè)務(wù)邏輯所必要的非敏感信息。

          4.Gateway

          1.使用Route結(jié)合Hystrix實(shí)現(xiàn)默認(rèn)降級(jí)策略

          2.使用接口,自定義過濾器類,實(shí)現(xiàn)登錄態(tài)(token)校驗(yàn)

          前端請(qǐng)求時(shí)path帶/gateway/,在gateway層使用=1,去掉gateway,最終微服務(wù)上的path不帶"/gateway/".

          使用Hystrix實(shí)現(xiàn)默認(rèn)降級(jí)策略,降級(jí)接口實(shí)現(xiàn)如下:

              @Slf4j
              @RestController
              public class DefaultHystrixController {
               
                  @RequestMapping("/defaultfallback")
                  public ApiResult defaultfallback(){
               
                      log.info("服務(wù)降級(jí)中");
                      return ApiResult.failure("服務(wù)異常");
                  }
              }
          

          4.1 實(shí)現(xiàn)登錄態(tài)(token)校驗(yàn)-自定義過濾器,實(shí)現(xiàn), Ordered 2個(gè)接口。

          import com.*.auth.UserTokenTools;
          import lombok.extern.slf4j.Slf4j;
          import org.apache.commons.lang3.StringUtils;
          import org.springframework.cloud.gateway.filter.GatewayFilter;
          import org.springframework.cloud.gateway.filter.GatewayFilterChain;
          import org.springframework.core.Ordered;
          import org.springframework.http.HttpHeaders;
          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.web.server.ServerWebExchange;
          import reactor.core.publisher.Mono;
           
          /**
           * @Description token過濾器
           */
          @Slf4j
          @Component
          public class LoginTokenFilter implements GatewayFilter, Ordered {
           
              private static final String AUTHORIZE_TOKEN = "Authorization";
              private static final String BEARER = "Bearer ";
           
              /**
               * token過濾
               *
          

          登錄過濾器怎么寫_java過濾器登錄驗(yàn)證_java 過濾器實(shí)現(xiàn)登錄

          * @param exchange * @param chain * @return */ @Override public Mono filter(ServerWebExchange exchange, GatewayFilterChain chain) { log.info("當(dāng)前環(huán)境已開啟token校驗(yàn)"); ServerHttpRequest request = exchange.getRequest(); HttpHeaders headers = request.getHeaders(); ServerHttpResponse response = exchange.getResponse(); // 取Authorization String tokenHeader = headers.getFirst(AUTHORIZE_TOKEN); log.info("tokenHeader=" + tokenHeader); // token不存在 if (StringUtils.isEmpty(tokenHeader)) { response.setStatusCode(HttpStatus.UNAUTHORIZED); return response.setComplete(); } // 取token String token = this.getToken(tokenHeader); log.info("token=" + token); // token不存在 if (StringUtils.isEmpty(token)) { log.info("token不存在"); response.setStatusCode(HttpStatus.UNAUTHORIZED); return response.setComplete(); } // 校驗(yàn) token是否失效 if (UserTokenTools.isTokenExpired(token, null)) { log.info("token失效"); response.setStatusCode(HttpStatus.UNAUTHORIZED); return response.setComplete(); } // 校驗(yàn) token是否正確 if (!UserTokenTools.checkToken(token, null)) { response.setStatusCode(HttpStatus.UNAUTHORIZED); return response.setComplete(); } // //有token 這里可根據(jù)具體情況,看是否需要在gateway直接把解析出來的用戶信息塞進(jìn)請(qǐng)求中,我們最終沒有使用 // UserTokenInfo userTokenInfo = UserTokenTools.getUserTokenInfo(token); // log.info("token={},userTokenInfo={}",token,userTokenInfo); // request.getQueryParams().add("token",token); //request.getHeaders().set("token", token); return chain.filter(exchange); } @Override public int getOrder() { return -10; } /** * 解析Token */ public String getToken(String requestHeader) { //2.Cookie中沒有從header中獲取 if (requestHeader != null && requestHeader.startsWith(BEARER)) { return requestHeader.substring(7); } return ""; } }

          4.2配置路由,可根據(jù)具體情況,如果只有一套登錄態(tài),那就用一個(gè)filter即可。

          java 過濾器實(shí)現(xiàn)登錄_登錄過濾器怎么寫_java過濾器登錄驗(yàn)證

          import com.*.gateway.filter.AuthorizeGatewayFilter;
          import com.*.gateway.filter.LoginTokenFilter;
          import org.springframework.cloud.gateway.route.RouteLocator;
          import org.springframework.cloud.gateway.route.builder.RouteLocatorBuilder;
          import org.springframework.context.annotation.Bean;
          import org.springframework.context.annotation.Configuration;
           
           
          @Configuration
          public class GatewayConfig {
           
              @Bean
              public RouteLocator getRouteLocator(RouteLocatorBuilder builder) {
                  return builder.routes()
                          // token校驗(yàn)1
                          .route(predicateSpec -> predicateSpec
                                  .path("/gateway/pay/card/**", "/gateway/app/**")
                                  .filters(gatewayFilterSpec -> gatewayFilterSpec.stripPrefix(1).filter(new AuthorizeGatewayFilter()))
                                  .uri("lb://OLOAN-PAY-SERVICE")
                                  .id("OLOAN-PAY-SERVICE-token"))
           
                          // token校驗(yàn)2
                          .route(predicateSpec -> predicateSpec
                                  .path("/gateway/order-audit/**", "/gateway/order/**", "/gateway/order-payment/**")
                                  .filters(gatewayFilterSpec -> gatewayFilterSpec.stripPrefix(1).filter(new LoginTokenFilter()))
                                  .uri("lb://OLOAN-ORDER-SERVICE")
                                  .id("OLOAN-ORDER-ORDER-token"))
                          .build();
              }
          }
          

          yml參考

          spring:
            cloud:
              gateway:
                discovery:
                  locator:
                    enabled: false
                    #開啟小寫驗(yàn)證,默認(rèn)feign根據(jù)服務(wù)名查找都是用的全大寫
                    lowerCaseServiceId: true
                default-filters:
                  - AddResponseHeader=X-Response-Default-Foo, Default-Bar
                routes:
                  - id: OLOAN-FINANCIAL-PRODUCT-SERVICE
                    # lb代表從注冊(cè)中心獲取服務(wù)
                    uri: lb://OLOAN-FINANCIAL-PRODUCT-SERVICE
                    predicates:
                      # 轉(zhuǎn)發(fā)該路徑
                      - Path=/gateway/financialProduct/**
                    # 帶前綴
                    filters:
                      - StripPrefix=1
                      - name: Hystrix
                        args:
                          name: fallbackcmd
                          fallbackUri: forward:/defaultfallback
                  - id: ADMIN-SERVICE
                    uri: lb://ADMIN-SERVICE
                    predicates:
                      - Path=/gateway/auth/**
                    filters:
                      - StripPrefix=2
                      - name: Hystrix
                        args:
                          name: fallbackcmd
          


          主站蜘蛛池模板: 色综合视频一区二区三区 | 日韩精品一区二区午夜成人版| 中文字幕一区二区三区在线观看 | 国产免费伦精品一区二区三区| 熟女少妇丰满一区二区| 国产精品一区二区四区| 亚洲一区二区影视| 无码人妻精品一区二区三区66| 中日av乱码一区二区三区乱码| 日韩少妇无码一区二区三区| 亚洲综合一区无码精品| 久久精品国产AV一区二区三区| 无码一区二区三区免费| 国产福利精品一区二区| 国产剧情国产精品一区| 中文字幕一精品亚洲无线一区| 亚洲av成人一区二区三区在线观看 | 色欲AV蜜桃一区二区三| 精品国产一区二区三区无码| 色一乱一伦一图一区二区精品| 国产精品日本一区二区不卡视频| 中文字幕亚洲一区二区三区| 国产精品 一区 在线| 精品视频在线观看你懂的一区| 精品久久国产一区二区三区香蕉| 日本一区二区三区中文字幕| 无码人妻AⅤ一区二区三区水密桃 无码欧精品亚洲日韩一区夜夜嗨 无码毛片一区二区三区中文字幕 无码毛片一区二区三区视频免费播放 | 国产一区二区三区在线免费观看 | 久久无码一区二区三区少妇 | 91久久精品国产免费一区| 精品一区二区三区在线成人| 精品三级AV无码一区| 精品人妻无码一区二区色欲产成人| 亚洲一区二区三区久久| 国产成人精品一区二三区熟女| 国产精品亚洲一区二区三区久久| 福利电影一区二区| 熟女少妇丰满一区二区| 亚洲一区二区三区乱码在线欧洲| 久久精品国内一区二区三区| 天天爽夜夜爽人人爽一区二区|