mysqls压力测试怎么用_用 Swagger 测试接口,怎么在请求头中携带 Token?
松哥周末抽空給 Spring Security 系列也錄制了一套視頻,目錄如下:
感興趣的小伙伴戳這里-->Spring Boot+Vue+微人事視頻教程
今天的話題來自一個小伙伴在微信上的提問:
看到這個問題,松哥忽然想到我自己之前寫過 Spring Boot+Swagger 的用法:
- SpringBoot 整合 Swagger2
也寫過 OAuth2 + Jwt 的用法:
- 想讓 OAuth2 和 JWT 在一起愉快玩耍?請看松哥的表演
但是還沒有將這兩個結合在一起寫過,所以小伙伴們對此有了疑問,想一想這還是一個非常常見的問題,因為現在使用令牌登錄的場景越來越多,在這種情況下,如果使用 Swagger 來測試接口,要怎么在請求頭中攜帶 Token 呢?今天松哥就來和大家聊一聊。
1.項目規劃
如果小伙伴們沒有看過松哥之前發的 OAuth2 系列文章,建議一定先看下(公眾號江南一點雨后臺回復 OAuth2 獲取),再來看本文內容,否則接下來的內容可能會犯迷糊。
這里松哥搭建一個 OAuth2+JWT 的環境來做演示。一共搭建兩個服務:
| auth-server | 8080 | 授權服務器 |
| user-server | 8081 | 資源服務器 |
我稍微解釋一下:
- auth-server 就是我的資源服務器,用來頒發 JWT 令牌。
- user-server 則是資源服務器,訪問 user-server 上的資源,都需要攜帶令牌才能訪問。
- swagger 則用來給 user-server 上的接口生成文檔。
OK,這是我們項目的一個大致規劃。
2.環境搭建
接下來我們來搭建 OAuth2 測試環境。
2.1 授權服務器搭建
首先我們搭建一個名為 auth-server 的授權服務,搭建的時候,選擇如下三個依賴:
- Web
- Spring Cloud Security
- Spirng Cloud OAuth2
項目創建完成后,首先提供一個 Spring Security 的基本配置:
@Configurationpublic?class?SecurityConfig?extends?WebSecurityConfigurerAdapter?{
????@Bean
????PasswordEncoder?passwordEncoder()?{
????????return?new?BCryptPasswordEncoder();
????}
????@Override
????@Bean
????public?AuthenticationManager?authenticationManagerBean()?throws?Exception?{
????????return?super.authenticationManagerBean();
????}
????@Override
????protected?void?configure(AuthenticationManagerBuilder?auth)?throws?Exception?{
????????auth.inMemoryAuthentication()
????????????????.withUser("sang")
????????????????.password(passwordEncoder().encode("123"))
????????????????.roles("admin")
????????????????.and()
????????????????.withUser("javaboy")
????????????????.password(passwordEncoder().encode("123"))
????????????????.roles("user");
????}
????@Override
????protected?void?configure(HttpSecurity?http)?throws?Exception?{
????????http.csrf().disable().formLogin();
????}
}
在這段代碼中,為了代碼簡潔,我就不把 Spring Security 用戶存到數據庫中去了,直接存在內存中。
這里我創建了一個名為 sang 的用戶,密碼是 123,角色是 admin。同時我還配置了一個表單登錄。
這段配置的目的,實際上就是配置用戶。例如你想用微信登錄第三方網站,在這個過程中,你得先登錄微信,登錄微信就要你的用戶名/密碼信息,那么我們在這里配置的,其實就是用戶的用戶名/密碼/角色信息。
需要注意的是,在當前案例中,我將采用 OAuth2 中的 password 模式進行登錄,因此這里還需要明確的提供一個 AuthenticationManager 的 Bean。
基本的用戶信息配置完成后,接下來我們來配置授權服務器。
首先來配置 TokenStore:
@Configurationpublic?class?AccessTokenConfig?{
????@Bean
????TokenStore?tokenStore()?{
????????return?new?JwtTokenStore(jwtAccessTokenConverter());
????}
????@Bean
????JwtAccessTokenConverter?jwtAccessTokenConverter()?{
????????JwtAccessTokenConverter?converter?=?new?JwtAccessTokenConverter();
????????converter.setSigningKey("javaboy");
????????return?converter;
????}
}
接下來對授權服務器進行詳細配置:
@EnableAuthorizationServer@Configuration
public?class?AuthorizationServer?extends?AuthorizationServerConfigurerAdapter?{
????@Autowired
????TokenStore?tokenStore;
????@Autowired
????ClientDetailsService?clientDetailsService;
????@Autowired
????AuthenticationManager?authenticationManager;
????@Autowired
????PasswordEncoder?passwordEncoder;
????@Autowired
????JwtAccessTokenConverter?jwtAccessTokenConverter;
????@Bean
????AuthorizationServerTokenServices?tokenServices()?{
????????DefaultTokenServices?services?=?new?DefaultTokenServices();
????????services.setClientDetailsService(clientDetailsService);
????????services.setSupportRefreshToken(true);
????????services.setTokenStore(tokenStore);
????????services.setAccessTokenValiditySeconds(60?*?60?*?24?*?2);
????????services.setRefreshTokenValiditySeconds(60?*?60?*?24?*?7);
????????TokenEnhancerChain?tokenEnhancerChain?=?new?TokenEnhancerChain();
????????tokenEnhancerChain.setTokenEnhancers(Arrays.asList(jwtAccessTokenConverter));
????????services.setTokenEnhancer(tokenEnhancerChain);
????????return?services;
????}
????@Override
????public?void?configure(AuthorizationServerSecurityConfigurer?security)?throws?Exception?{
????????security.allowFormAuthenticationForClients();
????}
????@Override
????public?void?configure(ClientDetailsServiceConfigurer?clients)?throws?Exception?{
????????clients.inMemory()
????????????????.withClient("javaboy")
????????????????.secret(passwordEncoder.encode("123"))
????????????????.resourceIds("res1")
????????????????.authorizedGrantTypes("password",?"refresh_token")
????????????????.scopes("all")
????????????????.redirectUris("http://localhost:8082/index.html");
????}
????@Override
????public?void?configure(AuthorizationServerEndpointsConfigurer?endpoints)?throws?Exception?{
????????endpoints
????????????????.authenticationManager(authenticationManager)
????????????????.tokenServices(tokenServices());
????}
}
這段代碼有點長,我來給大家挨個解釋:
好了,如此之后,我們的授權服務器就算是配置完成了,接下來我們啟動授權服務器。
如果小伙伴們對于上面的配置感到迷糊,可以在公眾號后臺回復 OAuth2,先系統的學習一下松哥的 OAuth2 教程。
2.2 資源服務器搭建
接下來我們搭建一個資源服務器。大家網上看到的例子,資源服務器大多都是和授權服務器放在一起的,如果項目比較小的話,這樣做是沒問題的,但是如果是一個大項目,這種做法就不合適了。
資源服務器就是用來存放用戶的資源,例如你在微信上的圖像、openid 等信息,用戶從授權服務器上拿到 access_token 之后,接下來就可以通過 access_token 來資源服務器請求數據。
我們創建一個新的 Spring Boot 項目,叫做 user-server ,作為我們的資源服務器,創建時,添加如下依賴:
項目創建成功之后,先把前面的 AccessTokenConfig 拷貝到資源服務器上,然后添加如下配置:
@Configuration@EnableResourceServer
public?class?ResourceServerConfig?extends?ResourceServerConfigurerAdapter?{
????@Autowired
????TokenStore?tokenStore;
????@Override
????public?void?configure(ResourceServerSecurityConfigurer?resources)?throws?Exception?{
????????resources.resourceId("res1").tokenStore(tokenStore);
????}
????@Override
????public?void?configure(HttpSecurity?http)?throws?Exception?{
????????http.authorizeRequests()
????????????????.antMatchers("/admin/**").hasRole("admin")
????????????????.anyRequest().authenticated();
????}
}
這段配置代碼很簡單,我簡單的說一下:
接下來我們再來配置兩個測試接口:
@RestControllerpublic?class?HelloController?{
????@GetMapping("/hello")
????public?String?hello()?{
????????return?"hello";
????}
????@GetMapping("/admin/hello")
????public?String?admin()?{
????????return?"admin";
????}
}
如此之后,我們的資源服務器就算配置成功了。
2.3 測試
分別啟動授權服務器和資源服務器,先訪問授權服務器獲取 access_token:
再利用拿到的 access_token 去訪問資源服務器:
OK,測試沒問題。
3.整合 Swagger
接下來,我們在 user-server 中加入 swagger 功能,首先我們加入 swagger 依賴:
?<dependency>?????<groupId>io.springfoxgroupId>
?????<artifactId>springfox-swagger2artifactId>
?????<version>2.9.2version>
?dependency>
?<dependency>
?????<groupId>io.springfoxgroupId>
?????<artifactId>springfox-swagger-uiartifactId>
?????<version>2.9.2version>
?dependency>
這里加入的依賴有兩個,一個用來生成接口數據,另一個 swagger-ui 用來做數據展示。
3.1 認證方式一
請求頭加參數,這里給大家介紹兩種,先來看第一種。
先配置一個 Docket 實例,如下:
@Configuration@EnableSwagger2
public?class?Swagger2Config?{
????@Bean
????Docket?docket()?{
????????return?new?Docket(DocumentationType.SWAGGER_2)
????????????????.select()
????????????????.apis(RequestHandlerSelectors.basePackage("org.javaboy.oauth2.res.controller"))
????????????????.paths(PathSelectors.any())
????????????????.build()
????????????????.securityContexts(Arrays.asList(securityContexts()))
????????????????.securitySchemes(Arrays.asList(securitySchemes()))
????????????????.apiInfo(new?ApiInfoBuilder()
????????????????????????.description("接口文檔的描述信息")
????????????????????????.title("微人事項目接口文檔")
????????????????????????.contact(new?Contact("javaboy","http://www.javaboy.org","wangsong0210@gmail.com"))
????????????????????????.version("v1.0")
????????????????????????.license("Apache2.0")
????????????????????????.build());
????}
????private?SecurityScheme?securitySchemes()?{
????????return?new?ApiKey("Authorization",?"Authorization",?"header");
????}
????private?SecurityContext?securityContexts()?{
????????return?SecurityContext.builder()
????????????????????????.securityReferences(defaultAuth())
????????????????????????.forPaths(PathSelectors.any())
????????????????????????.build();
????}
????private?List?defaultAuth()?{
????????AuthorizationScope?authorizationScope?=?new?AuthorizationScope("xxx",?"描述信息");
????????AuthorizationScope[]?authorizationScopes?=?new?AuthorizationScope[1];
????????authorizationScopes[0]?=?authorizationScope;
????????return?Arrays.asList(new?SecurityReference("Authorization",?authorizationScopes));
????}
}
這里的配置稍微有點長,我來給大家解釋下:
- 首先通過 @EnableSwagger2 注解啟用 Swagger2。
- 配置一個 Docket Bean,這個 Bean 中,配置映射路徑和要掃描的接口的位置。
- 在 apiInfo 中,主要配置一下 Swagger2 文檔網站的信息,例如網站的 title,網站的描述,聯系人的信息,使用的協議等等。
- 通過 securitySchemes 來配置全局參數,這里的配置是一個名為 Authorization 的請求頭(OAuth2 中需要攜帶的請求頭)。
- securityContexts 則用來配置有哪些請求需要攜帶 Token,這里我們配置了所有請求。
配置完成后,我們還需要給 swagger-ui 放行,否則 swagger-ui 相關的靜態資源會被 Spring Security 攔截下來:
@Configurationpublic?class?SecurityConfig?extends?WebSecurityConfigurerAdapter?{
????@Override
????public?void?configure(WebSecurity?web)?throws?Exception?{
????????web.ignoring().antMatchers("/swagger-ui.html")
????????????????.antMatchers("/webjars/**")
????????????????.antMatchers("/v2/**")
????????????????.antMatchers("/swagger-resources/**");
????}
}
配置完成后,重啟 user-server,瀏覽器輸入 http://localhost:8081/swagger-ui.html,結果如下:
大家可以看到,頁面中多了一個 Authorize 按鈕,點擊該按鈕,輸入 Bearer ${token},如下:
輸入完成后,點擊 Authorize 按鈕,完成認證,接下來,user-server 中的各種接口就可以直接調用測試了。
上面這種方式比較通用,不僅僅適用于 OAuth2,也適用于其他一些自定義的 token 登錄方式。
但是這種方式需要開發者先通過其他途徑獲取到 access_token,有的人會覺得這樣有點麻煩,那么有沒有更好的辦法呢?請看方式二。
3.2 認證方式二
認證方式二就是直接在 Swagger 中填入認證信息,這樣就不用從外部去獲取 access_token 了,效果如下:
我們來看下這個怎么配置。
由于 swagger 去請求 /oauth/token 接口會跨域,所以我們首先要修改 auth-server ,使之支持跨域:
主要是兩方面的修改,首先是配置 CorsFilter,允許跨域,如下:
@Configurationpublic?class?GlobalCorsConfiguration?{
????@Bean
????public?CorsFilter?corsFilter()?{
????????CorsConfiguration?corsConfiguration?=?new?CorsConfiguration();
????????corsConfiguration.setAllowCredentials(true);
????????corsConfiguration.addAllowedOrigin("*");
????????corsConfiguration.addAllowedHeader("*");
????????corsConfiguration.addAllowedMethod("*");
????????UrlBasedCorsConfigurationSource?urlBasedCorsConfigurationSource?=?new?UrlBasedCorsConfigurationSource();
????????urlBasedCorsConfigurationSource.registerCorsConfiguration("/**",?corsConfiguration);
????????return?new?CorsFilter(urlBasedCorsConfigurationSource);
????}
}
然后在 SecurityConfig 中開啟跨域支持:
@Configuration@Order(Ordered.HIGHEST_PRECEDENCE)
public?class?SecurityConfig?extends?WebSecurityConfigurerAdapter?{
????...
????...
????@Override
????protected?void?configure(HttpSecurity?http)?throws?Exception?{
????????http
????????????????.requestMatchers().antMatchers(HttpMethod.OPTIONS,?"/oauth/**")
????????????????.and()
????????????????.csrf().disable().formLogin()
????????????????.and()
????????????????.cors();
????}
}
經過這兩步的配置,服務端的跨域支持就開啟了。
接下來我們在 user-server 中修改關于 Docket bean 的定義:
@Configuration@EnableSwagger2
public?class?Swagger2Config?{
????@Bean
????Docket?docket()?{
????????return?new?Docket(DocumentationType.SWAGGER_2)
????????????????.select()
????????????????.apis(RequestHandlerSelectors.basePackage("org.javaboy.oauth2.res.controller"))
????????????????.paths(PathSelectors.any())
????????????????.build()
????????????????.securityContexts(Arrays.asList(securityContext()))
????????????????.securitySchemes(Arrays.asList(securityScheme()))
????????????????.apiInfo(new?ApiInfoBuilder()
????????????????????????.description("接口文檔的描述信息")
????????????????????????.title("微人事項目接口文檔")
????????????????????????.contact(new?Contact("javaboy","http://www.javaboy.org","wangsong0210@gmail.com"))
????????????????????????.version("v1.0")
????????????????????????.license("Apache2.0")
????????????????????????.build());
????}
????private?AuthorizationScope[]?scopes()?{
????????return?new?AuthorizationScope[]{
????????????????new?AuthorizationScope("all",?"all?scope")
????????};
????}
????private?SecurityScheme?securityScheme()?{
????????GrantType?grant?=?new?ResourceOwnerPasswordCredentialsGrant("http://localhost:8080/oauth/token");
????????return?new?OAuthBuilder().name("OAuth2")
????????????????.grantTypes(Arrays.asList(grant))
????????????????.scopes(Arrays.asList(scopes()))
????????????????.build();
????}
????private?SecurityContext?securityContext()?{
????????return?SecurityContext.builder()
????????????????.securityReferences(Arrays.asList(new?SecurityReference("OAuth2",?scopes())))
????????????????.forPaths(PathSelectors.any())
????????????????.build();
????}
}
這段配置跟前面的類似,主要是 SecurityScheme 不同。這里采用了 OAuthBuilder 來構建,構建時即得配置 token 的獲取地址。
好了,配置完成,重啟 auth-server 和 user-server 進行測試。測試效果就是松哥前面給出的圖片,不再贅述。
這種方式最大的好處就是不用通過其他途徑獲取 access_token,直接在 swagger-ui 頁面輸入 password 模式的認證參數即可。非常方便,僅限于 OAuth2 模式。
4.小結
好了,今天就和小伙伴們介紹了在 Swagger 請求中,如何修改請求頭的問題,感興趣的小伙伴可以下來試試哦~
本文案例下載地址:https://github.com/lenve/spring-security-samples
好啦,小伙伴們如果覺得有收獲,記得點個在看鼓勵下松哥哦~
今日干貨
剛剛發表查看:66666回復:666公眾號后臺回復 ssm,免費獲取松哥純手敲的 SSM 框架學習干貨。
總結
以上是生活随笔為你收集整理的mysqls压力测试怎么用_用 Swagger 测试接口,怎么在请求头中携带 Token?的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 安卓推送服务(安卓的推送)
- 下一篇: 安卓手机背景变黑色怎么改_别着急扔掉旧手