jwt-open
<p class="shortdesc">jwt-open插件是在Kong端启动一个JWT token生成服务(即不需要通过后端服务生成Token),根据插件配置的用户信息及服务信息生成一个JWT
token,可以配合JWT插件一起完成接口鉴权功能。</p>
<p class="p"><strong class="ph b">注:2.0.6-3版本及以上支持</strong></p>
<img class="image" id="jwt-open__image_hjl_ltw_2sb" src="https://obs-cn-shanghai.fincloud.pinganyun.com/pacloud/20220910180811-1817a94a9974.png" width="800">
<section class="section" id="jwt-open__section_p55_rtw_2sb"><h2 class="doc-tairway"><strong class="ph b">配置说明</strong></h2>
<ol class="ol" id="jwt-open__ol_qcf_qww_2sb">
<li class="li"><strong class="ph b">配置参数说明</strong>:<table class="table frame-all" id="jwt-open__table_rj4_sww_2sb"><caption><span class="table--title-label">表1 </span><span class="title"></span></caption><colgroup><col style="width:25%"><col style="width:25%"><col style="width:25%"><col style="width:25%"></colgroup><thead class="thead">
<tr class="row">
<th class="entry align-left colsep-1 rowsep-1" id="jwt-open__table_rj4_sww_2sb__entry__1">参数名</th>
<th class="entry align-left colsep-1 rowsep-1" id="jwt-open__table_rj4_sww_2sb__entry__2">参数类型</th>
<th class="entry align-left colsep-1 rowsep-1" id="jwt-open__table_rj4_sww_2sb__entry__3">是否必须</th>
<th class="entry align-left colsep-1 rowsep-1" id="jwt-open__table_rj4_sww_2sb__entry__4">参数说明</th>
</tr>
</thead><tbody class="tbody">
<tr class="row">
<td class="entry align-left colsep-1 rowsep-1" headers="jwt-open__table_rj4_sww_2sb__entry__1 ">iss</td>
<td class="entry align-left colsep-1 rowsep-1" headers="jwt-open__table_rj4_sww_2sb__entry__2 ">string</td>
<td class="entry align-left colsep-1 rowsep-1" headers="jwt-open__table_rj4_sww_2sb__entry__3 ">Y</td>
<td class="entry align-left colsep-1 rowsep-1" headers="jwt-open__table_rj4_sww_2sb__entry__4 ">关联JWT插件的JWT Key</td>
</tr>
<tr class="row">
<td class="entry align-left colsep-1 rowsep-1" headers="jwt-open__table_rj4_sww_2sb__entry__1 ">channel</td>
<td class="entry align-left colsep-1 rowsep-1" headers="jwt-open__table_rj4_sww_2sb__entry__2 ">string</td>
<td class="entry align-left colsep-1 rowsep-1" headers="jwt-open__table_rj4_sww_2sb__entry__3 ">Y</td>
<td class="entry align-left colsep-1 rowsep-1" headers="jwt-open__table_rj4_sww_2sb__entry__4 ">当前OpenAPI的渠道名,多个JWT-OPEN插件是通过channel来区分。</td>
</tr>
<tr class="row">
<td class="entry align-left colsep-1 rowsep-1" headers="jwt-open__table_rj4_sww_2sb__entry__1 ">secret</td>
<td class="entry align-left colsep-1 rowsep-1" headers="jwt-open__table_rj4_sww_2sb__entry__2 ">string</td>
<td class="entry align-left colsep-1 rowsep-1" headers="jwt-open__table_rj4_sww_2sb__entry__3 ">Y</td>
<td class="entry align-left colsep-1 rowsep-1" headers="jwt-open__table_rj4_sww_2sb__entry__4 ">生成JWT Token的私钥。base64加密后的数据</td>
</tr>
<tr class="row">
<td class="entry align-left colsep-1 rowsep-1" headers="jwt-open__table_rj4_sww_2sb__entry__1 ">users</td>
<td class="entry align-left colsep-1 rowsep-1" headers="jwt-open__table_rj4_sww_2sb__entry__2 ">array</td>
<td class="entry align-left colsep-1 rowsep-1" headers="jwt-open__table_rj4_sww_2sb__entry__3 ">Y</td>
<td class="entry align-left colsep-1 rowsep-1" headers="jwt-open__table_rj4_sww_2sb__entry__4 ">参考如下 USER数组数据格式</td>
</tr>
<tr class="row">
<td class="entry align-left colsep-1 rowsep-1" headers="jwt-open__table_rj4_sww_2sb__entry__1 ">groups</td>
<td class="entry align-left colsep-1 rowsep-1" headers="jwt-open__table_rj4_sww_2sb__entry__2 ">array</td>
<td class="entry align-left colsep-1 rowsep-1" headers="jwt-open__table_rj4_sww_2sb__entry__3 ">Y</td>
<td class="entry align-left colsep-1 rowsep-1" headers="jwt-open__table_rj4_sww_2sb__entry__4 ">参考如下 GROUP数组数据格式</td>
</tr>
</tbody></table><ul class="ul" id="jwt-open__ul_xsg_nxw_2sb">
<li class="li"><strong class="ph b">USER数组数据格式</strong><table class="table" id="jwt-open__table_s3d_4xw_2sb"><caption></caption><colgroup><col style="width:20%"><col style="width:20%"><col style="width:20%"><col style="width:20%"><col style="width:20%"></colgroup><thead class="thead">
<tr class="row">
<th class="entry align-left" id="jwt-open__table_s3d_4xw_2sb__entry__1">参数名</th>
<th class="entry align-left" id="jwt-open__table_s3d_4xw_2sb__entry__2">参数类型</th>
<th class="entry align-left" id="jwt-open__table_s3d_4xw_2sb__entry__3">是否必须</th>
<th class="entry align-left" id="jwt-open__table_s3d_4xw_2sb__entry__4">默认值</th>
<th class="entry align-left" id="jwt-open__table_s3d_4xw_2sb__entry__5">参数说明</th>
</tr>
</thead><tbody class="tbody">
<tr class="row">
<td class="entry align-left" headers="jwt-open__table_s3d_4xw_2sb__entry__1 ">um</td>
<td class="entry align-left" headers="jwt-open__table_s3d_4xw_2sb__entry__2 ">string</td>
<td class="entry align-left" headers="jwt-open__table_s3d_4xw_2sb__entry__3 ">Y</td>
<td class="entry align-left" headers="jwt-open__table_s3d_4xw_2sb__entry__4 "></td>
<td class="entry align-left" headers="jwt-open__table_s3d_4xw_2sb__entry__5 ">用户名,用户获取token时传入。</td>
</tr>
<tr class="row">
<td class="entry align-left" headers="jwt-open__table_s3d_4xw_2sb__entry__1 ">id</td>
<td class="entry align-left" headers="jwt-open__table_s3d_4xw_2sb__entry__2 ">string</td>
<td class="entry align-left" headers="jwt-open__table_s3d_4xw_2sb__entry__3 ">Y</td>
<td class="entry align-left" headers="jwt-open__table_s3d_4xw_2sb__entry__4 "></td>
<td class="entry align-left" headers="jwt-open__table_s3d_4xw_2sb__entry__5 ">用户ID,会写入JWT
Token中,方便后续服务进行数据鉴权。后续会优化为从后端接口获取。</td>
</tr>
<tr class="row">
<td class="entry align-left" headers="jwt-open__table_s3d_4xw_2sb__entry__1 ">secret</td>
<td class="entry align-left" headers="jwt-open__table_s3d_4xw_2sb__entry__2 ">string</td>
<td class="entry align-left" headers="jwt-open__table_s3d_4xw_2sb__entry__3 ">Y</td>
<td class="entry align-left" headers="jwt-open__table_s3d_4xw_2sb__entry__4 "></td>
<td class="entry align-left" headers="jwt-open__table_s3d_4xw_2sb__entry__5 ">客户端加密用的secret。如何使用请参考如下步骤说明后续会优化为从后端接口获取。</td>
</tr>
<tr class="row">
<td class="entry align-left" headers="jwt-open__table_s3d_4xw_2sb__entry__1 ">groups</td>
<td class="entry align-left" headers="jwt-open__table_s3d_4xw_2sb__entry__2 ">array</td>
<td class="entry align-left" headers="jwt-open__table_s3d_4xw_2sb__entry__3 ">Y</td>
<td class="entry align-left" headers="jwt-open__table_s3d_4xw_2sb__entry__4 "></td>
<td class="entry align-left" headers="jwt-open__table_s3d_4xw_2sb__entry__5 ">关联的接口权限组名称</td>
</tr>
</tbody></table></li>
<li class="li"><strong class="ph b">GROUP数组数据格式</strong><table class="table" id="jwt-open__table_ax1_pxw_2sb"><caption></caption><colgroup><col><col><col><col><col></colgroup><tbody class="tbody">
<tr class="row">
<td class="entry">参数名</td>
<td class="entry">参数类型</td>
<td class="entry">是否必须</td>
<td class="entry">默认值</td>
<td class="entry">参数说明</td>
</tr>
<tr class="row">
<td class="entry">name</td>
<td class="entry">string</td>
<td class="entry">Y</td>
<td class="entry"></td>
<td class="entry">接口权限组的名称,需要唯一</td>
</tr>
<tr class="row">
<td class="entry">expire_time</td>
<td class="entry">string</td>
<td class="entry">Y</td>
<td class="entry">60</td>
<td class="entry">接口权限组的过期时间,会影响到生成Token的有效时间单位秒,默认60s</td>
</tr>
<tr class="row">
<td class="entry">services</td>
<td class="entry">array</td>
<td class="entry">Y</td>
<td class="entry"></td>
<td class="entry">代理服务模块的代理服务名称。如果是所有服务可以配置为*</td>
</tr>
</tbody></table></li>
</ul></li>
<li class="li"><strong class="ph b">配置示例</strong><p class="p">插件路径:Authorization –>
jwt-open</p><pre class="pre codeblock" id="jwt-open__codeblock_un1_sxw_2sb"><code>{
"iss": "pae-openapi",
"channel": "pae-openapi",
"groups": [
{
"name": "group1",
"expire_time": 60,
"services": [
"pipeline-list",
"pipeline-execute"
]
}
],
"secret": "example",
"users": [
{
"um": "niujiangfei",
"groups": [
"group1"
],
"id": "c1b238e3-ba28-4f22-bfdb-e451a20b1a88",
"secret": "openapi-secret-niujiangfei"
}
]
}</code></pre></li>
</ol>
</section>
<section class="section" id="jwt-open__section_ww4_sxw_2sb"><h2 class="doc-tairway">步骤说明</h2>
<ol class="ol" id="jwt-open__ol_bqp_txw_2sb">
<li class="li"><strong class="ph b">准备工作</strong><p class="p">添加好jwt密钥。(此处用于JWT插件)</p><img class="image" id="jwt-open__image_olt_cyw_2sb" src="https://obs-cn-shanghai.fincloud.pinganyun.com/pacloud/20220910180811-1e433da1918c.png" width="800"><p class="p">添加好JWT插件。(此处可以参考JWT插件,用于对接口做鉴权,需要将获取token接口写入anonymous_urls中。)</p><img class="image" id="jwt-open__image_a3c_3yw_2sb" src="https://obs-cn-shanghai.fincloud.pinganyun.com/pacloud/20220910180811-1f496f4697f5.png" width="800"><p class="p">添加好代理服务。</p><p class="p">此处会添加获取Token的代理服务,后端服务地址固定为如图所示,路由规则可根据系统需求定制。</p><img class="image" id="jwt-open__image_e4j_qyw_2sb" src="https://obs-cn-shanghai.fincloud.pinganyun.com/pacloud/20220910180811-134650e2985f.png" width="800"></li>
<li class="li"><strong class="ph b">添加JWT-open插件</strong><p class="p">具体配置可见配置参数说明。</p></li>
<li class="li"><strong class="ph b">客户端获取Token</strong><p class="p">获取token时,调用Kong端/api/auth接口(此接口为第一步添加的代理服务),此接口做了数据加密认证、时间戳和防重放处理。具体请求header见如下图:</p><img class="image" id="jwt-open__image_qfs_1zw_2sb" src="https://obs-cn-shanghai.fincloud.pinganyun.com/pacloud/20220910180811-1bbe64ed905e.png" width="800"><table class="table" id="jwt-open__table_vp3_dzw_2sb"><caption></caption><colgroup><col><col><col><col></colgroup><tbody class="tbody">
<tr class="row">
<td class="entry">Header名</td>
<td class="entry">类型</td>
<td class="entry">是否必须</td>
<td class="entry">参数说明</td>
</tr>
<tr class="row">
<td class="entry">x-openapi-user</td>
<td class="entry">string</td>
<td class="entry">Y</td>
<td class="entry">即jwt-open插件配置中的用户um,如果传入的值不在配置中则返回认证失败。</td>
</tr>
<tr class="row">
<td class="entry">x-openapi-channel</td>
<td class="entry">string</td>
<td class="entry">Y</td>
<td class="entry">即jwt-open插件配置中的channel</td>
</tr>
<tr class="row">
<td class="entry">x-openapi-timestamp</td>
<td class="entry">array</td>
<td class="entry">Y</td>
<td class="entry">时间戳,与当前时间的时差必须在60s以内</td>
</tr>
<tr class="row">
<td class="entry">x-openapi-nonce</td>
<td class="entry">array</td>
<td class="entry">Y</td>
<td class="entry">防重放标识,需要保证在毫秒级别的唯一。用于验证60s以内的重复请求</td>
</tr>
<tr class="row">
<td class="entry">x-openapi-secret</td>
<td class="entry">array</td>
<td class="entry">Y</td>
<td class="entry">传入参数的加密串,具体加密方法如下所示</td>
</tr>
</tbody></table><p class="p">下面示例中的secret即用户配置中的secret。</p><pre class="pre codeblock" id="jwt-open__codeblock_zpr_dzw_2sb"><code>String originalStr = channel + ":" + um + ":" + timestamp + ":" + nonce;
String value = encodeHexString(signHS256(secret, originalStr.getBytes()));
System.out.println("crypt source string: "+originalStr);
System.out.println("crypt result string: "+value);
Map<String, String> authHeader = new HashMap<>();
authHeader.put("x-openapi-channel", channel);
authHeader.put("x-openapi-user", um);
authHeader.put("x-openapi-timestamp", timestamp+"");
authHeader.put("x-openapi-nonce", nonce);
authHeader.put("x-openapi-secret", value);
private static byte[] signHS256(String accessSecret, byte[] data){
Mac mac = HmacUtils.getInitializedMac(HmacAlgorithms.HMAC_SHA_256, accessSecret.getBytes());
return mac.doFinal(data);
}
private static String encodeHexString(byte[] data){
return Hex.encodeHexString(data);
}</code></pre><p class="p">请求成功示例如下:</p><pre class="pre codeblock" id="jwt-open__codeblock_ybn_fzw_2sb"><code>{
"code": 10000, // 成功时=1000
"data": "Bearer eyJhbGciOiJSUzI1NiJ9.eyJ1c2VySWQiOiJjMWIyMzhlMy1iYTI4LTRmMjItYmZkYi1lNDUxYTIwYjFhNDciLCJzZXJ2aWNlcyI6WyJwaXBlbGluZS1saXN0IiwicGlwZWxpbmUtZXhlY3V0ZSJdLCJpYXQiOjE2MjM3MjE5OTMsImlzcyI6InBhZS1vcGVuYXBpIiwiZXhwIjoxNjIzNzIyMDUzLCJzdWIiOiJuaXVqaWFuZ2ZlaTI1NiIsInR5cGUiOiJvcGVuYXBpIn0.oHfA_aTakTXd9A0t_ZieTZn-hdnIMIOeqZAKy8DpqLVBQUz6F1DPSuDcHH5oMH7m6_2lke6bAUrx5GB-2-hlo6lsXm2tMjkHqfYKXIIR35RazewRd24WGXO774C4EusyPY7XpfaEseIcWtlv3lVYRuq8LqsjCvgLv-MLo2NOKX3Sd7wgHzWcI2h3M-p0ywOU2MMGBfpYR32zL-IprUI1aWDW0iykY_MdQMlOcqa-mSuzFoprJTaV1ljxYV9mE4QEtCzFyH093JYTfv6G2fqQUXNRv7ZUDRx7MMqtMu7Txs9zhcOfK9eUub1WVL785lQzvv8wWILDU--0Nh60LH1AtA",
"message": "Success"
}</code></pre></li>
<li class="li"><strong class="ph b">客户端调用接口</strong><p class="p">请求其他接口时可以将上一步生成的Token写入header中,此header用于jwt插件的认证。(其他业务参数可按需添加)。</p><img class="image" id="jwt-open__image_h2d_mzw_2sb" src="https://obs-cn-shanghai.fincloud.pinganyun.com/pacloud/20220910180811-129616dc9cb1.png"></li>
</ol>
</section>
提交成功!非常感谢您的反馈,我们会继续努力做到更好!