如何在Swagger中自动获取并插入授权令牌(Java项目场景)
自动在Swagger请求中插入获取到的授权令牌
我之前刚好遇到过一模一样的需求,折腾了一阵后整理出两种可行的方案,根据你用的Swagger版本来选就行:
方案一:Springfox(旧版Swagger 2.x)自动注入令牌
1. 先写个令牌获取工具类
第一步要做的是封装一个能自动调用认证接口、缓存有效令牌的工具类,避免每次请求都重复调用令牌接口:
@Component public class AutoTokenProvider { private String cachedToken; private long tokenExpireTime; public String getValidToken() { // 先检查缓存的令牌是否还没过期 if (cachedToken != null && System.currentTimeMillis() < tokenExpireTime) { return cachedToken; } // 过期了就调用认证接口拿新令牌 RestTemplate restTemplate = new RestTemplate(); HttpHeaders headers = new HttpHeaders(); headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED); MultiValueMap<String, String> authParams = new LinkedMultiValueMap<>(); authParams.add("grant_type", "client_credentials"); // 根据你的认证模式调整 authParams.add("client_id", "your-service-client-id"); authParams.add("client_secret", "your-service-client-secret"); HttpEntity<MultiValueMap<String, String>> request = new HttpEntity<>(authParams, headers); ResponseEntity<TokenResp> tokenResp = restTemplate.postForEntity( "http://your-auth-server/api/token", request, TokenResp.class); if (tokenResp.getBody() != null) { cachedToken = tokenResp.getBody().getAccessToken(); // 提前10秒过期,避免刚好在请求时令牌失效 tokenExpireTime = System.currentTimeMillis() + (tokenResp.getBody().getExpiresIn() - 10) * 1000; return cachedToken; } throw new RuntimeException("Failed to fetch valid access token"); } // 内部类接收令牌接口返回的参数 private static class TokenResp { private String accessToken; private int expiresIn; // getter & setter public String getAccessToken() { return accessToken; } public void setAccessToken(String accessToken) { this.accessToken = accessToken; } public int getExpiresIn() { return expiresIn; } public void setExpiresIn(int expiresIn) { this.expiresIn = expiresIn; } } }
2. 修改SwaggerConfig配置
在你的SwaggerConfig.java里添加全局请求参数,动态注入令牌:
@Configuration @EnableSwagger2 public class SwaggerConfig { @Autowired private AutoTokenProvider tokenProvider; @Bean public Docket api() { return new Docket(DocumentationType.SWAGGER_2) .select() .apis(RequestHandlerSelectors.basePackage("com.your.project.package")) .paths(PathSelectors.any()) .build() .securitySchemes(Collections.singletonList(apiKey())) // 关键:添加自动填充的Authorization头 .globalRequestParameters(Collections.singletonList( new ParameterBuilder() .name("Authorization") .description("Auto-fetched JWT Token") .modelRef(new ModelRef("string")) .parameterType("header") .required(true) // 动态获取有效令牌,拼接Bearer前缀 .defaultValue(() -> "Bearer " + tokenProvider.getValidToken()) .build() )); } private ApiKey apiKey() { return new ApiKey("JWT", "Authorization", "header"); } }
配置完后,每次在Swagger页面发送请求时,系统会自动调用getValidToken()获取有效令牌,插入到请求头里,完全不用手动粘贴。
方案二:SpringDoc(新版OpenAPI 3.x)自动注入令牌
如果你的项目用的是SpringDoc(现在更推荐的Swagger替代方案),可以用OpenApiCustomiser来实现:
1. 复用上面的AutoTokenProvider工具类
逻辑和上面完全一致,直接拿来用就行。
2. 配置SpringDoc
@Configuration public class SpringDocConfig { @Autowired private AutoTokenProvider tokenProvider; @Bean public OpenAPI customOpenAPI() { return new OpenAPI() .components(new Components() .addSecuritySchemes("bearerAuth", new SecurityScheme() .type(SecurityScheme.Type.HTTP) .scheme("bearer") .bearerFormat("JWT"))) .addSecurityItem(new SecurityRequirement().addList("bearerAuth")); } @Bean public OpenApiCustomiser tokenAutoFillCustomiser() { return openApi -> { // 遍历所有接口操作,添加自动填充的Authorization头 openApi.getPaths().values().forEach(pathItem -> pathItem.readOperations().forEach(operation -> operation.addParametersItem(new Parameter() .name("Authorization") .in(ParameterIn.HEADER.toString()) .required(true) .schema(new StringSchema()._default("Bearer " + tokenProvider.getValidToken())) .description("Auto-generated access token")) ) ); }; } }
几个注意点
- 令牌缓存一定要做:不然每次请求都调用认证接口,不仅浪费资源,还可能触发认证服务的限流规则。
- 异常处理要完善:如果认证接口调用失败,要抛出明确的异常,避免Swagger页面直接挂掉。
- 认证模式适配:上面示例用的是
client_credentials模式,如果你用的是password或其他模式,要调整authParams里的参数。 - 权限校验:确保你用来获取令牌的
client_id和client_secret,拥有访问所有Swagger接口的权限。
我自己用第一种方案在生产环境跑了大半年,稳定性没问题,完全解放了手动粘贴令牌的麻烦。
内容的提问来源于stack exchange,提问作者homersimpson
相关产品推荐
相关产品推荐

