1.需求:现在A公司与B公司进行合作,B公司需要调用A公司开放的外网接口获取数据,如何保证外网开放接口的安全性?

2,使用令牌方式

比如支付宝对外提供支付的接口,爱乐生公司需要调用支付宝的接口。在爱乐生调用支付宝接口的时候,支付宝进行过滤器拦截,查看参数中的accessToken信息,是否能在redis缓存中的找到对应的公司,且同时对对方开放。如果没问题,则可以调用接口。

令牌的设计方式一般会设计到以下几个参数:

App_Name       表示机构名称

App_ID          应用id

App_Secret      应用密钥  (可更改)

Is_flag           是否可用 (是否对某个机构开放)

access_token  上一次access_token

API开放平台接口设计-------令牌方式-LMLPHP

3,生成accessToken 的接口:

package com.zfb.api.controller;

import java.util.UUID;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody; import com.zfb.base.Response;
import com.zfb.entity.AppEntity;
import com.zfb.mapper.AppMapper;
import com.zfb.response.IndexResponse;
import com.zfb.utils.BaseRedisService; @Controller
public class Index extends Response { @Autowired
private BaseRedisService baseRedisService;
@Autowired
private AppMapper appMapper; private static final long TIMEOUT = 60 * 60 * 60; @RequestMapping("/index")
@ResponseBody
private String index() {
return "index";
} @RequestMapping("/postAccessToken")
@ResponseBody
private String postAccessToken() {
AppEntity appEntity = new AppEntity();
appEntity.setAppId("1QA2was");//不可变
appEntity.setAppName("aiyusheng");
appEntity.setAppSecret("ssss");
appEntity.setId(1);
appEntity.setIsFlag(0);
getAccessToken(appEntity);
return "index";
}
/**
* 访问获取accessToken appid+appsecret 1,如果找这个机构,说明无权访问 2,如果if_flag为1,说明接口关闭了
* 3,如果找到这个机构,且为0的话,开始生成access_token 3.1,redis 缓存中先删除之前的access_oken
* 3.2,创建新的access_token,同时放入到缓存中
*
* @return
*/ @RequestMapping("/getAccessToken")
@ResponseBody
private String getAccessToken(AppEntity appEntity) {
AppEntity findApp = appMapper.findApp(appEntity);
// 如果找到这个机构,且为0的话,开始生成access_token
IndexResponse response = firstCheck(new IndexResponse(), findApp);
if (response.getRtnCode() != 200) {
return "fail";
}
String accessToken = findApp.getAccessToken();
baseRedisService.delKey(accessToken);
String generateAccessToken = generateAccessToken(findApp.getAppId(), findApp.getAppSecret());
//更新mysql 数据库
appMapper.updateAccessToken(generateAccessToken, appEntity.getAppId());
return "success";
} public String generateAccessToken(String appid, String appSecret) {
String accessToken = UUID.randomUUID().toString() + "_" + appid + "_" + appSecret;
baseRedisService.setString(accessToken, appid, TIMEOUT);
return accessToken;
} public IndexResponse firstCheck(IndexResponse indexResponse, AppEntity findApp) {
if (findApp == null) {
indexResponse.setResultError("没有对应的机构");
return null;
}
if (findApp.getIsFlag() != 0) {
indexResponse.setResultError("没有对" + findApp.getAppName() + "开放");
return indexResponse;
}
// 查询成功
indexResponse.setRtnCode(200);
return indexResponse;
} }

过滤器:

package com.zfb.filter;

import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired; import com.zfb.utils.BaseRedisService; @WebFilter(filterName = "tokenAccessFilter", urlPatterns = "/pay/*")
public class TokenAccessFilter implements Filter { @Autowired
private BaseRedisService baseRedisService; public void init(FilterConfig filterConfig) throws ServletException { } public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
String accessToken = request.getParameter("accessToken");
if (!StringUtils.isEmpty(accessToken)) {
//redis 里面的key 是 accessToken value是appid
String appid = (String) baseRedisService.getString(accessToken);
// 代表没有过期
if (!StringUtils.isEmpty(appid)) {
chain.doFilter(request, response);
}
} } public void destroy() { } }
05-28 04:24