一、 接口方式
接口調用采用http協議,rest請求方式;
二、 接口安全
接口安全采用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協議
三、 緩存配置
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"}
1. 鑒權TOKEN接口
■描述
根據用戶名和密碼獲取TOKEN。
■訪問地址
http://域名/rest/tokens
■訪問方式
GET
■參數
| 參數名 |
數據類型 |
是否必須 |
示例值 |
默認值 |
描述 |
| username |
String |
Y |
“admin” |
|
用戶名 |
| password |
String |
Y |
“123456” |
|
密碼 |
■返回值
成功時,直接返回token字符串。
失敗時,直接返回用戶賬號密碼錯誤!
■校驗規則
無
■請求示例
請求地址:http://域名/rest/tokens
- {
- "username":"admin",
- "password":"123456"
- }
■返回示例
成功案例:
- eyJhbGciOiJIUzI1NiJ9.eyJqdGkiOiI4YThhYjBiMjQ2ZGM4MTEyMDE0NmRjODE4MTk1MDA1MiIsInN1YiI6ImFkbWluIiwiaWF0IjoxNTExODU0NDE4fQ.tnILZEivS-6YOX9uqsnCHygh7-XrG_-Sj8vLslNGkdQ
- 失敗案例:
- 用戶賬號密碼錯誤!
2. 創建黑名單信息接口
■描述
創建黑名單信息接口,黑名單為單表。
■訪問地址
http://域名/rest/tsBlackListController
■訪問方式
POST
■參數(詳見excel)
| 參數名 |
數據類型 |
是否必須 |
示例值 |
默認值 |
描述 |
| ip |
String |
Y |
“192.168.1.1” |
|
|
| ...... |
|
|
……省略信息其他字段…… |
||
■返回值
| 參數名 |
描述 |
| 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":"黑名單創建失敗"
- }
3. 查詢黑名單信息接口
■描述
根據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查詢無結果"}
4. 修改黑名單信息接口
■描述
根據id修改
■訪問地址
http://域名/rest/tsBlackListController/update/{id}
■訪問方式
PUT
■參數
| 參數名 |
數據類型 |
是否必須 |
示例值 |
默認值 |
描述 |
| id |
String |
Y |
“402881f15f811877015f8124ca1c0002” |
|
|
| ip |
String |
Y |
“192.168.1.1” |
|
|
|
|
|
|
……省略信息其他字段…… |
||
■返回值
| 參數名 |
描述 |
| respCode |
返回碼(見附錄1接口返回信息列表) |
| respMsg |
返回信息(見附錄1接口返回信息列表) |
| data |
返回結果(NULL) |
| ok |
狀態 |
■校驗規則
通過校驗主表的字段:來源id和來源表驗證數據唯一性。
■請求示例
請求地址:http://域名/rest/tsBlackListController/update/402881f15f811877015f8124ca1c0002
參數如下:
- {
- "id": "402881e75f94878e015f94896bb80002",
- "ip": "1.1.1.1"
- }
■返回示例
- 成功案例:
- {
- "respCode":"0",
- "respMsg":"成功"
- }
- 失敗案例:
- {
- "respCode":"-1",
- "respMsg":"輸入ID無效,重復輸入"
- }
5. 刪除黑名單接口
■描述
根據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無效,重復輸入"
- }
五、 客戶端測試代碼
代碼示例
- 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.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));
- }
- }
- 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;
- }
- }
- 附錄1:接口返回CODE
| code |
msg |
說明 |
解決方案 |
| 0 |
SUCCESS |
成功 |
|
| -1 |
ERROR |
無接口訪問權限 |
|
| 1000 |
VALID_ERROR |
驗證失敗 |
|
| r0001 |
SAVE_SUCCESS |
寫入成功 |
|
| r0002 |
UPDATE_SUCCESS |
更新成功 |
|
| r0003 |
REMOVE_SUCCESS |
刪除成功 |
