Gradle中执行Curl命令时Auth Token错误的排查求助
问题描述
在SpringBoot微服务的build.gradle中执行以下代码调用接口:
def myCommand = "curl -X GET http://localhost:8405/my-accounts " + "-H Authorization:'Bearer JSUzUxMiIsInR5cCI6IkpXVCIsImtpZCI6ImIwZWM2ODhhZjAzZGQ3ODc1MTE2YmY2ZDM2YzM1MDIwODg2ZTQ4ODIifQ.eyJzdWIiOiJSM0NJU1VTRVIyIiwiYWNyIjoiSUFMMi5BQUwzLkZBTDEiLCJhdWQiOlsiVEJPUyJdLCJ1c2VyX25hbWUiOiJSM0NJU1VTRVIyIiwib20iLCJ4LXdkLXVzZXJ0eXBlIjoiRVhURVJOQUwiLCJzY29wZXMiOlsiQUxMLklOU1QtR0JMLlBBWU1FTlQuQUxMIiwiQUxMLklOU1QtR0JMLk9NTklBUFBTLkFMTCIsIkFMTC5JTlNULUdCTC5QUk9GSUxFLkFMTCIsIkFMTC5JTlNULUdCTC5SRVAuQUxMIiwiQUxMLklOU1QtR0JMLlJFQ0VJVkFCTEUuQUxMIiwiQUxMLklOU1QtR0JMLkNBUkQuQUxMIl0sImV4cCI6MjI4NDk3NTcxMzUzOCwibm9uY2UiOiJUQk9TIiwiY2xpZW50X2lkIjoiVEJPUyJ9.DS8YTDoNGS2xG_kxbCHGFhoRs3k-0M0IyuIeku-LIXJfqhR5qLRoxW0Za7qV9tn1lPDAnhV0vgvimNqe-4Eb_ZoIiPZL4mHBACS6rhH-bbMIEShfFOerVC20_csr4po0T89t251k4_wxSR557NryxeBtO4QX_sJLthfaVkVS9CngeTOPnc31_wAr33e36KysGlSgDoZMmrwcu7KSYCVMLr2doc5J0wcIcKaK_AAn_bW-ds6UsZpFCXZ1-wIjreoH03GHH8-z9db2Qv6KPJKIOsOxy-0T5n0xXTmJnZHPFDzHHPWktDCxBlqIpWGw-XRBf1U0xtCOPQ' " ProcessBuilder builder = new ProcessBuilder(myCommand.split(' ')); Process process = builder.start(); process.waitFor() InputStream stdout = process.getInputStream() BufferedReader reader = new BufferedReader(new InputStreamReader(stdout)) println reader.readLine()
执行后返回错误:
{ "timestamp": "2023-03-20T11:32:16.866+00:00", "status": 500, "error": "Internal Server Error", "message": "The token was expected to have 3 parts, but got 1.", "path": "/my-accounts", "errors": [{ "field": "root", "message": "Internal Server Error" }] }
但在命令行执行完全相同的curl命令却能正常返回结果,说明Token本身有效:
curl -X GET http://localhost:8405/dompay-accounts -H Authorization:"Bearer JSUzUxMiIsInR5cCI6IkpXVCIsImtpZCI6ImIwZWM2ODhhZjAzZGQ3ODc1MTE2YmY2ZDM2YzM1MDIwODg2ZTQ4ODIifQ.eyJzdWIiOiJSM0NJU1VTRVIyIiwiYWNyIjoiSUFMMi5BQUwzLkZBTDEiLCJhdWQiOlsiVEJPUyJdLCJ1c2VyX25hbWUiOiJSM0NJU1VTRVIyIiwib20iLCJ4LXdkLXVzZXJ0eXBlIjoiRVhURVJOQUwiLCJzY29wZXMiOlsiQUxMLklOU1QtR0JMLlBBWU1FTlQuQUxMIiwiQUxMLklOU1QtR0JMLk9NTklBUFBTLkFMTCIsIkFMTC5JTlNULUdCTC5QUk9GSUxFLkFMTCIsIkFMTC5JTlNULUdCTC5SRVAuQUxMIiwiQUxMLklOU1QtR0JMLlJFQ0VJVkFCTEUuQUxMIiwiQUxMLklOU1QtR0JMLkNBUkQuQUxMIl0sImV4cCI6MjI4NDk3NTcxMzUzOCwibm9uY2UiOiJUQk9TIiwiY2xpZW50X2lkIjoiVEJPUyJ9.DS8YTDoNGS2xG_kxbCHGFhoRs3k-0M0IyuIeku-LIXJfqhR5qLRoxW0Za7qV9tn1lPDAnhV0vgvimNqe-4Eb_ZoIiPZL4mHBACS6rhH-bbMIEShfFOerVC20_csr4po0T89t251k4_wxSR557NryxeBtO4QX_sJLthfaVkVS9CngeTOPnc31_wAr33e36KysGlSgDoZMmrwcu7KSYCVMLr2doc5J0wcIcKaK_AAn_bW-ds6UsZpFCXZ1-wIjreoH03GHH8-z9db2Qv6KPJKIOsOxy-0T5n0xXTmJnZHPFDzHHPWktDCxBlqIpWGw-XRBf1U0xtCOPQ"
尝试了以下几种请求头写法,均未解决问题:
-H Authorization:'Bearer JSUzUx...'→ 报相同错误-H Authorization:Bearer JSUzUx...→ 报相同错误-H Authorization:\"Bearer JSUzUx...\"→ 无任何响应/错误-H Authorization:\"'Bearer JSUzUx...'\"→ 无任何响应/错误
解决方案
问题根源是使用split(' ')拆分命令时,会把Authorization头的内容错误拆分:单引号会被当成参数的一部分,导致实际传递给服务器的Token只有'Bearer片段,因此触发“Token应包含3部分但仅收到1部分”的错误。
正确做法是直接给ProcessBuilder传递独立参数列表,避免字符串拆分的问题:
def token = "JSUzUxMiIsInR5cCI6IkpXVCIsImtpZCI6ImIwZWM2ODhhZjAzZGQ3ODc1MTE2YmY2ZDM2YzM1MDIwODg2ZTQ4ODIifQ.eyJzdWIiOiJSM0NJU1VTRVIyIiwiYWNyIjoiSUFMMi5BQUwzLkZBTDEiLCJhdWQiOlsiVEJPUyJdLCJ1c2VyX25hbWUiOiJSM0NJU1VTRVIyIiwib20iLCJ4LXdkLXVzZXJ0eXBlIjoiRVhURVJOQUwiLCJzY29wZXMiOlsiQUxMLklOU1QtR0JMLlBBWU1FTlQuQUxMIiwiQUxMLklOU1QtR0JMLk9NTklBUFBTLkFMTCIsIkFMTC5JTlNULUdCTC5QUk9GSUxFLkFMTCIsIkFMTC5JTlNULUdCTC5SRVAuQUxMIiwiQUxMLklOU1QtR0JMLlJFQ0VJVkFCTEUuQUxMIiwiQUxMLklOU1QtR0JMLkNBUkQuQUxMIl0sImV4cCI6MjI4NDk3NTcxMzUzOCwibm9uY2UiOiJUQk9TIiwiY2xpZW50X2lkIjoiVEJPUyJ9.DS8YTDoNGS2xG_kxbCHGFhoRs3k-0M0IyuIeku-LIXJfqhR5qLRoxW0Za7qV9tn1lPDAnhV0vgvimNqe-4Eb_ZoIiPZL4mHBACS6rhH-bbMIEShfFOerVC20_csr4po0T89t251k4_wxSR557NryxeBtO4QX_sJLthfaVkVS9CngeTOPnc31_wAr33e36KysGlSgDoZMmrwcu7KSYCVMLr2doc5J0wcIcKaK_AAn_bW-ds6UsZpFCXZ1-wIjreoH03GHH8-z9db2Qv6KPJKIOsOxy-0T5n0xXTmJnZHPFDzHHPWktDCxBlqIpWGw-XRBf1U0xtCOPQ" ProcessBuilder builder = new ProcessBuilder( "curl", "-X", "GET", "http://localhost:8405/my-accounts", "-H", "Authorization:Bearer " + token ); Process process = builder.start(); process.waitFor() InputStream stdout = process.getInputStream() BufferedReader reader = new BufferedReader(new InputStreamReader(stdout)) println reader.readLine()
这种方式会将每个参数独立传递,不需要给Header值加单/双引号,ProcessBuilder会自动处理参数边界,确保Authorization头完整传递给服务器。
内容的提问来源于stack exchange,提问作者Shabar
相关产品推荐
相关产品推荐

