当前位置: 首页 > news >正文

怎样制作网站建设方案网站优化seo培

怎样制作网站建设方案,网站优化seo培,b2c网站运营方案,seo怎么做关键词排名文章目录一、使用背景二、实现方案三、具体流程四、优化五、代码实现六、后续优化一、使用背景 过去对于接口的验证我一般都是直接在登录时为用户发放token,用户在随后的操作中携带了token则允许请求。 但是这样的验证方式存在有一定的问题,如果token被…

文章目录

      • 一、使用背景
      • 二、实现方案
      • 三、具体流程
      • 四、优化
      • 五、代码实现
      • 六、后续优化

一、使用背景

过去对于接口的验证我一般都是直接在登录时为用户发放token,用户在随后的操作中携带了token则允许请求。

但是这样的验证方式存在有一定的问题,如果token被泄露被他人获取,那么就会有非法请求的风险。其他人可以使用这个token自行调用接口进行请求,传入非法参数甚至进行注入攻击等,可能会造成严重的问题。

即存在以下安全问题:

  • 请求身份是否合法
  • 请求参数是否被篡改

为了防止这种情况的发生,我们验证接收到的数据与客户端发送的数据一致,且让接口只能被客户端请求。

二、实现方案

既然要实现接口只能被客户端请求,那么我们不难想到可以与客户端达成某些约定,让客户端按一定的规则发送请求。

只需要服务端与客户端约定一套密钥,客户端在发送请求时拼接上私钥后使用单向加密算法进行加密,服务端收到后使用相同的私钥和加密算法进行加密后验证是否与前端客户端传递的值相同。

这样的方案可以使得用户即使拿到了token没有私钥的话加密后的数据与服务端加密后的肯定不相同而无法通过验证。篡改参数同样会产生相同的问题,从而保证了接口的安全性。

三、具体流程

  • 按照请求参数名的字母升序排列非空请求参数(包含accesskey),使用URL键值对的格式(即key1=value1&key2=value2…)拼接成字符串A;
  • 在字符串A最后拼接上secretkey得到字符串B;
  • 对B进行MD5运算,并将得到的字符串所有字符转换为大写,得到sign值;
  • 携带参数accesskey和sign进行请求

四、优化

以上方式虽然解决了非法用户请求和请求参数被篡改的问题,但是还存在着重复使用请求参数伪造二次请求的隐患。

为了解决这个问题我们不难想到请求时生成一个唯一的标识符,那么服务端在接收到请求之后只需要验证是否已经接受过改请求的标识即可。

不过以上方式还存在一个问题就是服务端要保存那么多的请求标识并不现实,所以我们可以设置一个过期时间,过期了就将标识删除。并让请求的时候携带一个时间戳,超过时间的请求直接打回。

五、代码实现

假设请求接口:test?param1=hello&param2=world

那么前端需要发送请求:test?accesskey=xxx&param1=hello&param2=world&nonce=随机唯一标识&timestamp=当前时间戳&sign=xxx

sign = MD5(“accesskey=xxx&nonce=随机唯一标识&param1=hello&param2=world&secretkey=xxx&timestamp=当前时间戳”).toUpperCase()

注意请求接口中的参数可以不按顺序,而用于生成sign的字符串中的各个参数必须按照一定的顺序(与后端约定)

后端验签:

@Component
public class ApiVerifyUtil {public static final String SECRET_KEY = "secretkey";public static final String ACCESS_KEY = "accesskey";public static final String TIMESTAMP_KEY = "timestamp";public static final String NONCE_KEY = "nonce";public static final String SIGN_KEY = "sign";private static final HashMap<String, String> KEY_PAIR;static {KEY_PAIR = new HashMap<>();KEY_PAIR.put("app1", "password1");  // 为客户端分配的密钥KEY_PAIR.put("app2", "password2");}@Autowiredprivate RedisTemplate<String, String> redisTemplateBean;private static RedisTemplate<String, String> redisTemplate;@PostConstructpublic void init() {redisTemplate = redisTemplateBean;}public static final Integer OK = 0;public static final Integer PARAMS_ERROR = 1;public static final Integer LACK_ACCESSKEY = 2;public static final Integer ACCESSKEY_INVALID = 3;public static final Integer LACK_NONCE = 4;public static final Integer LACK_TIMESTAMP = 5;public static final Integer LACK_SIGN = 6;public static final Integer REQUEST_TIMEOUT = 7;public static final Integer REQUEST_REPEATED = 8;public static final Integer REQUEST_INVALID = 9;// 超时时间(ms)public static final long TIMEOUT = 1000 * 60 * 15;public static final String AND = "&";public static final String EQUALS = "=";public static Integer verify(HashMap<String, String> params) {if (params == null || params.isEmpty()) {return PARAMS_ERROR;}// accessKey为空或不合法(即不存在对应的密钥)或请求参数不全则直接打回String accessKey, secretKey, timestamp, nonce, sign;if ((accessKey = params.get(ACCESS_KEY)) == null) {return LACK_ACCESSKEY;}if ((secretKey = KEY_PAIR.get(accessKey)) == null) {return ACCESSKEY_INVALID;}if ((timestamp = params.get(TIMESTAMP_KEY)) == null) {return LACK_TIMESTAMP;} else if (Long.parseLong(timestamp) - System.currentTimeMillis() > TIMEOUT) {// 超过15分钟return REQUEST_TIMEOUT;}if ((nonce = params.get(NONCE_KEY)) == null) {return LACK_NONCE;} else {Set<String> nonceSet = redisTemplate.opsForSet().members("nonce");if (nonceSet != null && nonceSet.contains(nonce)) {return REQUEST_REPEATED;}}if ((sign = params.get(SIGN_KEY)) == null) {return LACK_SIGN;}params.remove(SIGN_KEY);// 加密需要拼接上密钥params.put(SECRET_KEY, secretKey);ArrayList<String> keyList = new ArrayList<>(params.keySet());// 按顺序构造Collections.sort(keyList);StringBuilder sb = new StringBuilder();for (String key : keyList) {sb.append(key).append("=").append(params.get(key)).append("&");}String newSign = sb.toString();newSign = MD5.create().digestHex16(newSign.substring(0, newSign.length() - 1).toUpperCase());if (newSign.equals(sign)) {redisTemplate.opsForSet().add("nonce", nonce);return OK;}return REQUEST_INVALID;}public static HashMap<String, String> getParams(HttpServletRequest httpServletRequest) {String queryString = httpServletRequest.getQueryString();String[] split = queryString.split(AND);HashMap<String, String> params = new HashMap<>();for (String param : split) {params.put(param.split(EQUALS)[0], param.split(EQUALS)[1]);}return params;}public static HashMap<String, String> getParams(String queryString) {String[] split = queryString.split(AND);HashMap<String, String> params = new HashMap<>();for (String param : split) {params.put(param.split(EQUALS)[0], param.split(EQUALS)[1]);}return params;}}

六、后续优化

  1. 加入接口被调用的阈值限制,对接口访问频率设置一定阈值,对超过阈值的请求进行屏蔽及预警。
  2. 白名单机制:指定一些可以访问我们暴露接口的域名,不在白名单里面的域名发过来的请求,直接拒绝。
http://www.ds6.com.cn/news/31547.html

相关文章:

  • wordpress有留言时邮件提醒网站推广专家十年乐云seo
  • 如手机网站源码百度数据中心
  • 网站开发语言哪一种好些成人速成班有哪些专业
  • 苏州网络推广成都网站seo服务
  • 公司网站建设有用吗刷关键词优化排名
  • 做湘菜的网站昆明seo网站建设
  • 四川做网站百度知道网页入口
  • 阿里巴巴国际站可以做网站吗关键词是网站seo的核心工作
  • 学校网站网站建设seo排名关键词
  • 网站开发ui公司推广策划方案
  • 深圳建站模板购买软件开发公司推荐
  • 公司做社交网站诈骗网建
  • 网站评论回复如何做实时热榜
  • 网站制作东莞seo网络营销外包
  • 如何免费做网站网页北京seo技术
  • 苏州手机网站建设服务西安百度推广优化公司
  • 榆林做网站电话企业快速建站
  • 网站收录入口申请企业网站的类型
  • 在哪个网站订酒店做申根签证seo服务哪家好
  • 派遣公司做网站的好处杭州百度推广代理商
  • 各类最牛网站建设如何做品牌宣传与推广
  • 网站是怎么优化推广的北京seo人员
  • 创业做网站站长之家ping
  • 内部优惠券网站怎么做百家港 seo服务
  • 郫县做网站数据分析网官网
  • 找公司做网站需要注意网络推广的工作内容是什么
  • 制作网站工具友情链接qq群
  • 外网建筑设计网站seo主管招聘
  • 中企动力邮箱seo三人行网站
  • 网站维护北京外贸营销网站建设介绍