转载:https://www.cnblogs.com/jeecg158/p/8427208.html
接口调用采用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和端口。
[java] view plain copy #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接口】以外的接口时,都需要访问用户拥有对接口的访问权限,如无权限,将直接返回如下信息:
[java] view plain copy {"message":"您没有该接口的权限!","data":null,"ok":false,"respCode":"-1"}■描述
根据用户名和密码获取TOKEN。
■访问地址
http://域名/rest/tokens
■访问方式
GET
■参数
参数名
数据类型
是否必须
示例值
默认值
描述
username
String
Y
“admin”
用户名
password
String
Y
“123456”
密码
■返回值
成功时,直接返回token字符串。
失败时,直接返回用户账号密码错误!
■校验规则
无
■请求示例
请求地址:http://域名/rest/tokens
[java] view plain copy { "username":"admin", "password":"123456" }■返回示例
成功案例:
[java] view plain copy eyJhbGciOiJIUzI1NiJ9.eyJqdGkiOiI4YThhYjBiMjQ2ZGM4MTEyMDE0NmRjODE4MTk1MDA1MiIsInN1YiI6ImFkbWluIiwiaWF0IjoxNTExODU0NDE4fQ.tnILZEivS-6YOX9uqsnCHygh7-XrG_-Sj8vLslNGkdQ 失败案例: 用户账号密码错误!■描述
创建黑名单信息接口,黑名单为单表。
■访问地址
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和来源表。
[java] view plain copy { "ip": "192.1.1.1", ……(省略信息其他字段) }■返回示例
[java] view plain copy 成功案例: { "respCode":"0", " respMsg":"成功" } 失败案例: { "respCode":"-1", "respMsg":"黑名单创建失败" }■描述
根据id查询或查询黑名单信息接口。
■访问地址
根据id查询
http://域名/rest/tsBlackListController/get/{id}
■访问方式
GET
■参数
无
■返回值
参数名
描述
respCode
返回码(见附录1接口返回信息列表)
respMsg
返回信息(见附录1接口返回信息列表)
data
返回结果(结构参照创建企业接口的参数,具体字段参照excel)
ok
状态
■校验规则
■请求示例
请求地址:http://域名
[java] view plain copy /rest/tsBlackListController/get/297e7ae15f7f7f7e015f7fb0f57e0040■返回示例
[java] view plain copy 成功案例: { "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 } [java] view plain copy 失败案例: {"data":null,"respCode":"-1","respMsg":"根据所传id查询无结果"}■描述
根据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
参数如下:
[java] view plain copy { "id": "402881e75f94878e015f94896bb80002", "ip": "1.1.1.1" }■返回示例
[java] view plain copy 成功案例: { "respCode":"0", "respMsg":"成功" } 失败案例: { "respCode":"-1", "respMsg":"输入ID无效,重复输入" }■描述
根据id删除
■访问地址
http://域名/rest/tsBlackListController/delete/{id}
■访问方式
DELETE
■参数
无
■返回值
参数名
描述
respCode
返回码(见附录1接口返回信息列表)
respMsg
返回信息(见附录1接口返回信息列表)
data
返回结果(NULL)
ok
状态
■校验规则
无
■请求示例
请求地址:http://域名/rest/tsBlackListController/delete/297e7ae15f7f7f7e015f7fb0f57e0040
■返回示例
[java] view plain copy 成功案例: { "respCode":"0", "respMsg":"成功" } 失败案例: { "respCode":"-1", "respMsg":"输入ID无效,重复输入" }代码示例
[java] view plain copy 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; } 参考源码: [java] view plain copy 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)); } } [java] view plain copy 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:接口返回CODEcode
msg
说明
解决方案
0
SUCCESS
成功
-1
ERROR
无接口访问权限
1000
VALID_ERROR
验证失败
r0001
SAVE_SUCCESS
写入成功
r0002
UPDATE_SUCCESS
更新成功
r0003
REMOVE_SUCCESS
转载于:https://www.cnblogs.com/Jeely/p/11303556.html
相关资源:JAVA上百实例源码以及开源项目