平臺JWT接口文檔
===
**目錄索引:**
- 接口方式
- 接口安全
- 緩存配置
- 接口說明
- 在線接口文檔
- 客戶端測試代碼
- 接口案例
# 平臺JWT接口文檔
## 一、接口方式
接口調用采用http協議,restful請求方式;
## 二、接口安全
接口安全采用Json web token (JWT)機制,基于token的鑒權機制.
### 1.機制說明
基于token的鑒權機制類似于http協議也是無狀態的,它不需要在服務端去保留用戶的認證信息或者會話信息。這就意味著基于token認證機制的應用不需要去考慮用戶在哪一臺服務器登錄了,這就為應用的擴展提供了便利。
### 2.基本流程
流程上是這樣的:
(1)用戶使用用戶名密碼來請求服務器
(2)服務器進行驗證用戶的信息
(3)服務器通過驗證發送給用戶一個token
(4)客戶端存儲token,并在每次請求時附送上這個token值(存在head里的參數X-AUTH-TOKEN)
(5)服務端驗證token值,并返回數據

### 3.優點
* 因為json的通用性,所以JWT是可以進行跨語言支持的,像JAVA,JavaScript,NodeJS,PHP等很多語言都可以使用。
* 因為有了payload部分,所以JWT可以在自身存儲一些其他業務邏輯所必要的非敏感信息。
* 便于傳輸,jwt的構成非常簡單,字節占用很小,所以它是非常便于傳輸的。
* 它不需要在服務端保存會話信息, 所以它易于應用的擴展
### 4.安全相關
* 不應該在jwt的payload部分存放敏感信息,因為該部分是客戶端可解密的部分。
* 保護好secret私鑰,該私鑰非常重要。
* 如果可以,請使用https協議
### 5.鑒權TOKEN接口
##### (1)描述
根據用戶名和密碼獲取TOKEN。
##### (2)訪問地址
http://域名/rest/tokens
##### (3)訪問方式
GET
##### (4)參數
| 參數名| 數據類型| 是否必須| 示例值| 默認值| 描述|
| -------- | ----- | ---- |
| username| String| Y| “admin”| | 用戶名|
| password| String| Y| “123456”| | 密碼|
##### (5)返回值
成功時,直接返回token字符串。
失敗時,直接返回用戶賬號密碼錯誤!
##### (6)校驗規則
無
##### (7)請求示例
請求地址:http://域名/rest/tokens
```
{
"username":"admin",
"password":"123456"
}
```
##### (8)返回示例
```
成功案例:
eyJhbGciOiJIUzI1NiJ9.eyJqdGkiOiI4YThhYjBiMjQ2ZGM4MTEyMDE0NmRjODE4MTk1MDA1MiIsInN1YiI6ImFkbWluIiwiaWF0IjoxNTExODU0NDE4fQ.
tnILZEivS-6YOX9uqsnCHygh7-XrG_-Sj8vLslNGkdQ
失敗案例:
用戶賬號密碼錯誤!
```
## 三、緩存配置
JWT 驗證token采用redis進行緩存,
redis配置文件:src/main/resources/redis.properties
修改redis對應的IP和端口。
```
#redis
redis.host=124.206.91.99
redis.port=6379
redis.pass=
redis.adapter.maxIdle=100
redis.adapter.minIdle=10
redis.adapter.testOnBorrow=true
redis.adapter.testOnReturn=true
redis.adapter.testWhileIdle=true
redis.adapter.numTestsPerEvictionRun=10
redis.adapter.timeBetweenEvictionRunsMillis=60000
```
## 四、接口說明
**注意:**訪問除【鑒權TOKEN接口】以外的接口時,都需要訪問用戶擁有對接口的訪問權限,如無權限,將直接返回如下信息:
```
{"message":"您沒有該接口的權限!","data":null,"ok":false,"respCode":"-1"}
```
## 五、在線接口文檔
集成Swagger-ui 實現在線接口文檔,訪問地址:
http://localhost:8080/jeecg/swagger/index.html
效果如圖:

## 六、客戶端測試代碼
* 代碼示例
```
public static String getToken(String userName,String password){
String url = "http://localhost:8080/jeecg/rest/tokens?username="+userName+"&password="+password;
String token= JwtHttpUtil.httpRequest(url, "POST", null);
return token;
}
//獲取黑名單列表
public static JSONObject getBlackList(String token){
String url = "http://localhost:8080/jeecg/rest/tsBlackListController";
JSONObject resp= JwtHttpUtil.httpRequest(url, "GET", null,token);
return resp;
}
//創建黑名單
public static JSONObject createBlackList(String token,String json){
String url = "http://localhost:8080/jeecg/rest/tsBlackListController";
JSONObject resp= JwtHttpUtil.httpRequest(url, "POST", json,token);
return resp;
}
//更新黑名單
public static JSONObject updateBlackList(String token,String json){
String url = "http://localhost:8080/jeecg/rest/tsBlackListController";
JSONObject resp= JwtHttpUtil.httpRequest(url, "PUT", json,token);
return resp;
}
//刪除黑名單
public static JSONObject deleteBlackList(String token,String id){
String url = "http://localhost:8080/jeecg/rest/tsBlackListController/"+id;
JSONObject resp= JwtHttpUtil.httpRequest(url, "DELETE", null,token);
return resp;
}
//查詢黑名單
public static JSONObject getBlackList(String token,String id){
String url = "http://localhost:8080/jeecg/rest/tsBlackListController/"+id;
JSONObject resp= JwtHttpUtil.httpRequest(url, "GET", null,token);
return resp;
```
* 參考源碼:
```
package org.jeecgframework.jwt.util;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.ConnectException;
import java.net.HttpURLConnection;
import java.net.URL;
import org.jeecgframework.core.util.LogUtil;
import com.alibaba.fastjson.JSONObject;
/**
* JWT 客戶端
* @author qinfeng
*
*/
public class JwtHttpUtil {
/**
* 發起https請求并獲取結果
*
* @param requestUrl
* 請求地址
* @param requestMethod
* 請求方式(GET、POST)
* @param outputStr
* 提交的數據
* @return JSONObject(通過JSONObject.get(key)的方式獲取json對象的屬性值)
*/
public static JSONObject httpRequest(String requestUrl, String requestMethod, String outputStr, String sign) {
JSONObject jsonObject = null;
StringBuffer buffer = new StringBuffer();
HttpURLConnection httpUrlConn = null;
try {
// 創建SSLContext對象,并使用我們指定的信任管理器初始化
URL url = new URL(requestUrl);
httpUrlConn = (HttpURLConnection) url.openConnection();
httpUrlConn.setDoOutput(true);
httpUrlConn.setDoInput(true);
httpUrlConn.setUseCaches(false);
httpUrlConn.setRequestProperty("X-AUTH-TOKEN", sign);
httpUrlConn.setRequestProperty("Accept", "*/*");
httpUrlConn.setRequestProperty("Content-Type", "application/json");
// 設置請求方式(GET/POST)
httpUrlConn.setRequestMethod(requestMethod);
if ("GET".equalsIgnoreCase(requestMethod))
httpUrlConn.connect();
// 當有數據需要提交時
if (null != outputStr) {
OutputStream outputStream = httpUrlConn.getOutputStream();
// 注意編碼格式,防止中文亂碼
outputStream.write(outputStr.getBytes("UTF-8"));
outputStream.close();
}
// 將返回的輸入流轉換成字符串
InputStream inputStream = httpUrlConn.getInputStream();
InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "utf-8");
BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
String str = null;
while ((str = bufferedReader.readLine()) != null) {
buffer.append(str);
}
bufferedReader.close();
inputStreamReader.close();
// 釋放資源
inputStream.close();
inputStream = null;
httpUrlConn.disconnect();
System.out.println(buffer.toString());
jsonObject = JSONObject.parseObject(buffer.toString());
// jsonObject = JSONObject.fromObject(buffer.toString());
} catch (ConnectException ce) {
LogUtil.info("Weixin server connection timed out.");
} catch (Exception e) {
e.printStackTrace();
org.jeecgframework.core.util.LogUtil.info("https request error:{}" + e.getMessage());
} finally {
try {
httpUrlConn.disconnect();
} catch (Exception e) {
e.printStackTrace();
org.jeecgframework.core.util.LogUtil.info("http close error:{}" + e.getMessage());
}
}
return jsonObject;
}
/**
* 發起https請求并獲取結果
*
* @param requestUrl
* 請求地址
* @param requestMethod
* 請求方式(GET、POST)
* @param outputStr
* 提交的數據
* @return JSONObject(通過JSONObject.get(key)的方式獲取json對象的屬性值)
*/
public static String httpRequest(String requestUrl, String requestMethod, String outputStr) {
String res = "";
StringBuffer buffer = new StringBuffer();
HttpURLConnection httpUrlConn = null;
try {
// 創建SSLContext對象,并使用我們指定的信任管理器初始化
URL url = new URL(requestUrl);
httpUrlConn = (HttpURLConnection) url.openConnection();
httpUrlConn.setDoOutput(true);
httpUrlConn.setDoInput(true);
httpUrlConn.setUseCaches(false);
httpUrlConn.setRequestProperty("Accept", "text/plain");
httpUrlConn.setRequestProperty("Content-Type", "application/json");
// 設置請求方式(GET/POST)
httpUrlConn.setRequestMethod(requestMethod);
if ("GET".equalsIgnoreCase(requestMethod))
httpUrlConn.connect();
// 當有數據需要提交時
if (null != outputStr) {
OutputStream outputStream = httpUrlConn.getOutputStream();
// 注意編碼格式,防止中文亂碼
outputStream.write(outputStr.getBytes("UTF-8"));
outputStream.close();
}
// 將返回的輸入流轉換成字符串
InputStream inputStream = httpUrlConn.getInputStream();
InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "utf-8");
BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
String str = null;
while ((str = bufferedReader.readLine()) != null) {
buffer.append(str);
}
bufferedReader.close();
inputStreamReader.close();
// 釋放資源
inputStream.close();
inputStream = null;
httpUrlConn.disconnect();
res = buffer.toString();
System.out.println(res);
// jsonObject = JSONObject.parseObject(buffer.toString());
// jsonObject = JSONObject.fromObject(buffer.toString());
} catch (ConnectException ce) {
LogUtil.info("Weixin server connection timed out.");
} catch (Exception e) {
e.printStackTrace();
org.jeecgframework.core.util.LogUtil.info("https request error:{}" + e.getMessage());
} finally {
try {
httpUrlConn.disconnect();
} catch (Exception e) {
e.printStackTrace();
org.jeecgframework.core.util.LogUtil.info("http close error:{}" + e.getMessage());
}
}
return res;
}
}
```
```
package org.jeecgframework.test.demo;
import org.jeecgframework.jwt.util.JwtHttpUtil;
import com.alibaba.fastjson.JSONObject;
/**
* jeecg jwt
* 接口客戶端調用demo
* @author qinfeng
*
*/
public class JwtRestfulClientDemo {
public static String getToken(String userName,String password){
String url = "http://localhost:8080/jeecg/rest/tokens?username="+userName+"&password="+password;
String token= JwtHttpUtil.httpRequest(url, "POST", null);
return token;
}
//獲取黑名單列表
public static JSONObject getBlackList(String token){
String url = "http://localhost:8080/jeecg/rest/tsBlackListController";
JSONObject resp= JwtHttpUtil.httpRequest(url, "GET", null,token);
return resp;
}
//創建黑名單
public static JSONObject createBlackList(String token,String json){
String url = "http://localhost:8080/jeecg/rest/tsBlackListController";
JSONObject resp= JwtHttpUtil.httpRequest(url, "POST", json,token);
return resp;
}
//更新黑名單
public static JSONObject updateBlackList(String token,String json){
String url = "http://localhost:8080/jeecg/rest/tsBlackListController";
JSONObject resp= JwtHttpUtil.httpRequest(url, "PUT", json,token);
return resp;
}
//刪除黑名單
public static JSONObject deleteBlackList(String token,String id){
String url = "http://localhost:8080/jeecg/rest/tsBlackListController/"+id;
JSONObject resp= JwtHttpUtil.httpRequest(url, "DELETE", null,token);
return resp;
}
//查詢黑名單
public static JSONObject getBlackList(String token,String id){
String url = "http://localhost:8080/jeecg/rest/tsBlackListController/"+id;
JSONObject resp= JwtHttpUtil.httpRequest(url, "GET", null,token);
return resp;
}
public static void main(String[] args) {
String token = getToken("interfaceuser","123456");
// String token = "eyJhbGciOiJIUzI1NiJ9.eyJqdGkiOiJhZG1pbiIsInN1YiI6ImFkbWluIiwiaWF0IjoxNTExODU5NjM2fQ.Emfe8VZKA_L33jaW8ZUtVFVDEin83Np_d3gKlPIZryE";
// System.out.println(token);
//添加黑名單
// JSONObject jsonObject=new JSONObject();
// jsonObject.put("ip","192.168.1.2");
// System.out.println("======添加黑名單======="+createBlackList(token,jsonObject.toJSONString()));
//更新黑名單
// JSONObject jsonObject=new JSONObject();
// jsonObject.put("id","402881ee6001da57016001dc13110001");
// jsonObject.put("ip","192.168.0.111");
// System.out.println("======更新黑名單======="+updateBlackList(token,jsonObject.toJSONString()));
//刪除黑名單
// System.out.println("======刪除黑名單======="+deleteBlackList(token,"402881ee6001da57016001dc13110001"));
//查詢黑名單
// System.out.println("======查詢黑名單======="+getBlackList(token,"402881ee6001e873016001f369f40008"));
//獲取黑名單列表
System.out.println("======獲取黑名單列表======="+getBlackList(token));
}
}
```
## 七、接口案例
### 1.創建黑名單信息接口
* 描述
創建黑名單信息接口,黑名單為單表。
* 訪問地址
http://域名/rest/tsBlackListController
* 訪問方式
POST
* 參數(詳見excel)

* 返回值
| 參數名| 描述|
| -------- | ----- | ---- |
| respCode| 返回碼(見附錄1接口返回信息列表)|
| respMsg| 返回信息(見附錄1接口返回信息列表)|
| data| 返回結果(NULL)|
| ok| 狀態|
* 校驗規則
1. 接口中涉及日期時間的字段,要求格式化為字符串傳遞,日期格式為“YYYY-MM-dd”,時間格式為“YYYY-MM-dd HH:mm:ss”。
* 請求示例
請求地址:http://域名/rest/tsBlackListController
參數如下:
注意:創建企業無需傳id,子表無需傳id和企業id,這些都會在后臺生成,必需要傳入的是來源id和來源表。
```
{
"ip": "192.1.1.1",
……(省略信息其他字段)
}
```
* 返回示例
```
成功案例:
{
"respCode":"0",
" respMsg":"成功"
}
失敗案例:
{
"respCode":"-1",
"respMsg":"黑名單創建失敗"
}
```
### 2.查詢黑名單信息接口
* 描述
根據id查詢或查詢黑名單信息接口。
* 訪問地址
根據id查詢:http://域名/rest/tsBlackListController/get/{id}
* 訪問方式
GET
* 參數
無
* 返回值
| 參數名| 描述|
| -------- | ----- | ---- |
| respCode| 返回碼(見附錄1接口返回信息列表)|
| respMsg| 返回信息(見附錄1接口返回信息列表)|
| data| 返回結果(結構參照創建企業接口的參數,具體字段參照excel)|
| ok| 狀態|
* 校驗規則
* 請求示例
* 請求地址:http://域名/rest/tsBlackListController/get/297e7ae15f7f7f7e015f7fb0f57e0040
* 返回示例
```
成功案例:
{
"message": "成功",
"data": {
"id": "402881f15e751d2a015e75212c570005",
"createBy": "admin",
"updateBy": "",
"bpmStatus": "1",
"ip": "111.193.210.4",
"createName": "管理員",
"createDate": "2017-09-12 16:07:41",
"updateName": "",
"updateDate": null,
"sysOrgCode": "A03",
"sysCompanyCode": "A03"
},
"respCode": "0",
"ok": true
}
```
```
失敗案例:
{"data":null,"respCode":"-1","respMsg":"根據所傳id查詢無結果"}
```
### 3.修改黑名單信息接口
* 描述
根據id修改
* 訪問地址
http://域名/rest/tsBlackListController/update/{id}
* 訪問方式
PUT
* 參數

* 返回值
| 參數名| 描述|
| -------- | ----- | ---- |
| respCode| 返回碼(見附錄1接口返回信息列表)|
| respMsg| 返回信息(見附錄1接口返回信息列表)|
| data| 返回結果(NULL)|
| ok| 狀態|
* 校驗規則
1.通過校驗主表的字段:來源id和來源表驗證數據唯一性。
* 請求示例
請求地址:http://域名/rest/tsBlackListController/update/402881f15f811877015f8124ca1c0002
參數如下:
```
{
"id": "402881e75f94878e015f94896bb80002",
"ip": "1.1.1.1"
}
```
* 返回示例
```
成功案例:
{
"respCode":"0",
"respMsg":"成功"
}
失敗案例:
{
"respCode":"-1",
"respMsg":"輸入ID無效,重復輸入"
}
```
### 4.刪除黑名單接口
* 描述
根據id刪除
* 訪問地址
http://域名/rest/tsBlackListController/delete/{id}
* 訪問方式
DELETE
* 參數
無
* 返回值
| 參數名| 描述|
| -------- | ----- | ---- |
| respCode| 返回碼(見附錄1接口返回信息列表)|
| respMsg| 返回信息(見附錄1接口返回信息列表)|
| data| 返回結果(NULL)|
| ok| 狀態|
* 校驗規則
無
* 請求示例
請求地址:http://域名/rest/tsBlackListController/delete/297e7ae15f7f7f7e015f7fb0f57e0040
* 返回示例
```
成功案例:
{
"respCode":"0",
"respMsg":"成功"
}
失敗案例:
{
"respCode":"-1",
"respMsg":"輸入ID無效,重復輸入"
}
```
**附錄1:**
接口返回CODE
| code| msg| 說明| 解決方案|
| --- | --- | --- |
| 0| SUCCESS| 成功| |
| -1| ERROR| 無接口訪問權限| |
| 1000| VALID_ERROR| 驗證失敗| |
| r0001| SAVE_SUCCESS| 寫入成功| |
| r0002| UPDATE_SUCCESS| 更新成功| |
| r0003| REMOVE_SUCCESS| 刪除成功| | |
- 總體介紹
- 快速了解
- 平臺優勢
- 技術支持
- 社區榮譽
- 開發環境準備
- JEECG私服Maven
- 代碼結構說明
- 入門開發環境搭建
- 開發工具
- 代碼生成器使用
- GUI代碼生成器
- Online代碼生成器
- P3插件代碼生成器
- 代碼生成器配置
- 功能介紹
- 權限開發手冊
- Online開發權限
- Online表單訪問規則
- 列表按鈕權限控制
- 列表數據權限控制
- 頁面表單權限控制(一對多表)
- 頁面表單權限控制(單表)
- 其他
- 二級管理員手冊
- 接口權限配置
- 平臺權限設計總覽
- 編碼開發方式
- 列表按鈕權限用法
- 列表數據權限用法
- 數據權限自定義SQL
- 表單權限用法
- UI標簽庫文檔
- AuthFilter(頁面權限標簽)
- Autocomplete(自動補全標簽)
- BaseTag(樣式和JS引入標簽)
- Choose(彈出選擇標簽)
- ComboTree(下拉樹形選擇框)
- Datagrid(數據列表標簽)
- DepartSelectTag(部門樹選擇標簽)
- DictSelect(數據字典下拉選擇框)
- FormValidation(表單提交及驗證標簽)
- HasPermissionTag(頁面權限標簽)
- Menu(左側菜單生成標簽)
- MutiLang(國際化標簽)
- OrgSelectTag(部門樹列表選擇標簽)
- SelectZTree(Ztree樹控件)
- Tabs(選項卡父標簽)
- TreeSelectTag樹分類標簽
- Upload(上傳標簽)
- UserSelectTag(用戶選擇標簽)
- WebUploader(上傳標簽)
- 查詢構造器
- 查詢過濾器
- 高級查詢構造器
- 專題功能介紹
- 國際化使用
- 多數據源使用
- 定時任務
- 平臺JWT接口文檔
- 消息中心
- Online在線開發
- Online二次開發
- Online代碼生成
- Online唯一性校驗配置
- Online查詢機制(數據權限)
- Online樹形表單配置
- Online表單填值規則
- Online表單對外接口
- Online表單控件
- Online表單配置
- Online表單高級應用
- Online報表開發
- Online圖形報表配置
- Online數據報表配置
- Online移動報表配置
- 自定義表單設計
- 自定義表單權限
- 列表空間權限控制
- 功能介紹
- 常規控件權限控制
- 自定義表單配置
- 自定義表單二次開發
- 自定義表單控件
- 自定義表單數據源
- 自定義表單模板
- 自定義表單配置
- 自定義表單高級應用
- 表單數據維護
- 附錄小技巧
- datagrid擴展屬性用法
- Formvalid新增屬性tiptype的使用
- JEECG單點集成文檔
- Jeecg定時任務開發
- JEECG常見問題貼
- Redis與Ehcache切換文檔
- Toolbar自定義js參數規則
- UI標簽規則
- 列表多表頭的設計
- 列表拓展字段展示
- 列表自定義查詢條件
- 員工入職開發規范文檔V1.0
- 數據列表合計功能
- 登錄權限攔截器排除方法
- 組織機構導入功能使用說明
- 表單字段重復校驗方法
- JEECG新技術
- 新版UI技術方案