当前位置:首页>文章>网站防篡改设备(篡改常识的系统最新章节)

网站防篡改设备(篡改常识的系统最新章节)

什么是Api接口幂等? 简单来说Api接口幂等在有限的时间内限制接口访问请求,限制ip访问次数,不限制平台访问,都可以拿到数据。一个接口不可以重复表单提交,生产一次消费一次。 用户场景:同一时间重复提交多次请求。 什么是数据篡改? api接口数据篡改,脚本文件,篡改接口参数进行服务器数据窃取,严重的数据篡改会导致数据库宕机,程序软件崩溃。 想到这里都知道后台api接口幂等多重要了吧。今天给大家讲非...

什么是Api接口幂等?

简单来说Api接口幂等在有限的时间内限制接口访问请求,限制ip访问次数,不限制平台访问,都可以拿到数据。一个接口不可以重复表单提交,生产一次消费一次。

用户场景:同一时间重复提交多次请求。

什么是数据篡改?

api接口数据篡改,脚本文件,篡改接口参数进行服务器数据窃取,严重的数据篡改会导致数据库宕机,程序软件崩溃。

想到这里都知道后台api接口幂等多重要了吧。今天给大家讲非对称加密实现后台接口api幂等。

实现思路:jtw+ 验证标识+签名密钥+当前时间戳+存放过期时间+AES 实现加密算法token。

实现步骤:1,用户登录成功后,生产加密token存放redis.

2,下次登录检验token 是否过期,过期请重新登录。

3,用户登录存在有效期,不需要登录。(这里就是单点登录方式)

code核心实现类:


import io.jsonwebtoken.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.User;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import javax.annotation.PostConstruct;
import javax.servlet.http.HttpServletRequest;
import java.util.*;
import java.util.stream.Collectors;

@Component
public class JWTTokenUtils {

	public static final String AUTHORIZATION_HEADER = \"x-token\";

	public static final String AUTHORIZATION_TOKEN = \"x-token\";
	private final Logger logger = LoggerFactory.getLogger(JWTTokenUtils.class);
	private static final String AUTHORITIES_KEY = \"auth\";
	private String secretKey; // 签名密钥
	private long tokenValidityInMilliseconds; // 失效日期
	private long tokenValidityInMillisecondsForRememberMe; // (记住我)失效日期

	@PostConstruct
	public void init() {
		this.secretKey = \"isoftstone.huwei\";
		int secondIn1day = 1000 * 60 * 60 * 24;
		this.tokenValidityInMilliseconds = secondIn1day * 2L;
		this.tokenValidityInMillisecondsForRememberMe = secondIn1day * 7L;
	}

	// 创建Token
	public String createToken(Authentication authentication, Boolean rememberMe) {
		String authorities = authentication.getAuthorities().stream() // 获取用户的权限字符串,如 USER,ADMIN
				.map(GrantedAuthority::getAuthority).collect(Collectors.joining(\",\"));
		long now = (new Date()).getTime(); // 获取当前时间戳
		Date validity; // 存放过期时间
		if (rememberMe) {
			validity = new Date(now + this.tokenValidityInMilliseconds);
		} else {
			validity = new Date(now + this.tokenValidityInMillisecondsForRememberMe);
		}
		return SysConst.SYS_COMPANY_HEAD+\".\"+ Jwts.builder() // 创建Token令牌
				.setSubject(authentication.getName()) // 设置面向用户
				.claim(AUTHORITIES_KEY, authorities) // 添加权限属性
				.setExpiration(validity) // 设置失效时间
				.signWith(SignatureAlgorithm.HS512, secretKey) // 生成签名
				.compact();
	}

	// 获取用户权限
	public Authentication getAuthentication(String token) {
		logger.info(\"JWTTokenUtils Start Get User Auth\");
		// 解析Token的payload
		Claims claims = Jwts.parser().setSigningKey(secretKey).parseClaimsJws(token).getBody();
		Collection<? extends GrantedAuthority> authorities = Arrays
				.stream(claims.get(AUTHORITIES_KEY).toString().split(\",\")) // 获取用户权限字符串
				.map(SimpleGrantedAuthority::new).collect(Collectors.toList()); // 将元素转换为GrantedAuthority接口集合
		User principal = new User(claims.getSubject(), \"\", authorities);
		return new UsernamePasswordAuthenticationToken(principal, null, authorities);
	}
	/**
	 * 解析token获取用户编码
	 * @param token
	 * @return
	 */
	public String getAuthSubject(String token) {
		Claims claims = Jwts.parser().setSigningKey(secretKey).parseClaimsJws(token).getBody();
		return claims.getSubject();
	}
	
	public String resolveToken(HttpServletRequest request){
        String bearerToken = request.getHeader(AUTHORIZATION_HEADER);         //从HTTP头部获取TOKEN
        if (StringUtils.hasText(bearerToken) && bearerToken.startsWith(SysConst.SYS_COMPANY_HEAD)){
            return bearerToken.substring(bearerToken.indexOf(\".\")+1, bearerToken.length());                              //返回Token字符串,去除Bearer
        }
        String jwt = request.getParameter(AUTHORIZATION_TOKEN);               //从请求参数中获取TOKEN
        if (StringUtils.hasText(jwt) && jwt.startsWith(SysConst.SYS_COMPANY_HEAD)) {
            return jwt.substring(bearerToken.indexOf(\".\")+1, jwt.length());
        }
        return null;
    }

	// 验证Token是否正确
	public boolean validateToken(String token) {
		try {
			Jwts.parser().setSigningKey(secretKey).parseClaimsJws(token); // 通过密钥验证Token
			return true;
		}  catch (MalformedJwtException e) { // JWT格式错误
			logger.info(\"Invalid JWT token.\");
			logger.trace(\"Invalid JWT token trace: {}\", e);
		} catch (ExpiredJwtException e) { // JWT过期
			logger.info(\"Expired JWT token.\");
			logger.trace(\"Expired JWT token trace: {}\", e);
		} catch (UnsupportedJwtException e) { // 不支持该JWT
			logger.info(\"Unsupported JWT token.\");
			logger.trace(\"Unsupported JWT token trace: {}\", e);
		} catch (IllegalArgumentException e) { // 参数错误异常
			logger.info(\"JWT token compact of handler are invalid.\");
			logger.trace(\"JWT token compact of handler are invalid trace: {}\", e);
		}catch (SignatureException e) { // 签名异常
			logger.info(\"Invalid JWT signature.\");
			logger.trace(\"Invalid JWT signature trace: {}\", e);
		}
		return false;
	}
}

redis写入缓存:

   RedisModel model = new RedisModel();
   model.setModelName(token);
   model.setModelKey(\"userInfo\");
   Map<String,Object> params = new HashMap<String,Object>();
   params.put(\"userName\", customerDto.getUsername());
   CustomerVo customerVo = new CustomerVo();
   customerVo.setEmail(customerDto.getEmail());
   customerVo.setPhone(customerDto.getPhone());
   CustomerVo userInfo = customerService.queryUserByUserName(customerVo);
   Map<String,Object> userToken = new HashMap<String,Object>();
   userToken.put(\"userToken\", token);
   userToken.put(\"userInfo\", userInfo);
   model.setModelData(userToken);
   model.setTimeoutType(\"M\");
   model.setTimeout(redisTokenTimeOut);
   resultMap.setCode(CommonResultStatus.SUCCESS.getCode());
   resultMap.setMessage(CommonResultStatus.SUCCESS.getMessage());
   //写入为hash实体
   redisTemplate.opsForHash().put(model.getModelName(), model.getModelKey(), model.getModelData());
   redisTemplate.expire(model.getModelName(), model.getTimeout(), TimeUnit.MINUTES);
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
 public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
	public static final String AUTHORIZATION_HEADER = \"x-token\";//Authorization

	//允许访问的路径
	private static final String[] AUTH_WITHOUTLIST = {
			// -- swagger ui
			\"/v2/api-docs\", \"/swagger-resources\", \"/swagger-resources/**\", \"/configuration/ui\",
			\"/configuration/security\", \"/swagger-ui.html\", \"/webjars/**\",
			// other public endpoints of your API may be appended to this array
			\"/druid/**\",\"/health\",\"/info\",\"/info/**\",//druid sql 监听
			\"/hystrix\",\"/hystrix/**\",\"/error\",\"/loggers\",\"/loggers/**\",
			\"/service-registry/instance-status\",\"/hystrix.stream\",\"/turbine/**\",\"/turbine.stream\",
			\"/autoconfig\",\"/archaius\",\"/beans\",\"/features\",\"/configprops\",\"/mappings\",\"/auditevents\",
			\"/env\",\"/env/**\",\"/metrics\",\"/metrics/**\",\"/trace\",\"/trace/**\", \"/dump\",\"/dump/**\", \"/jolokia/**\",
			\"/info/**\",\"/activiti/**\", \"/logfile/**\", \"/refresh\",\"/flyway/**\", \"/liquibase/**\",\"/heapdump\",\"/heapdump/**\",
			\"/v1/authcenter/login\",\"/v1/authcenter/fiberhomeLogin\",\"/v1/authcenter/registered\",//登录URL
			\"/v1/authcenter/queryAuthInfo\",//鉴权URL
			\"/u/sms/sendPhone\",\"/citry/getChineseProvinces\",\"/code/getCaptchaImage\",\"/u/sms/forgetEmailPwd\",
			\"/u/sms/sendEmail\",\"/citry/getOtherCoutryList\",\"/upload/pngDir/*\",\"/job/getJobList\",\"/u/sms/sendLoginEmail\",
			\"/v1/authcenter/queryUserInfoByMap\",\"/v1/authcenter/forgetPwd\",
			\"/diagram-viwmer/**\",\"/editor-marketing/**\",
			\"/modeler.html\",
			\"/actuator/health\"
	};

	@Autowired
	private SecurityUserDetailsService securityUserDetailsService;
	@Autowired
	private AuthLogoutSuccessHandler authLogoutSuccessHandler;
	@Autowired
	private JWTTokenUtils tokenProvider;



	@Override
	protected void configure(AuthenticationManagerBuilder auth) throws Exception {
		//自定义获取用户信息设置密码加密  和默认用DaoAuthenticationProvider加密任选
		auth.userDetailsService(securityUserDetailsService).passwordEncoder(passwordEncoder());
	}

	@Override
	protected void configure(HttpSecurity http) throws Exception {
		// 配置请求访问策略
		// 关闭CSRF、CORS
		http.cors().disable().csrf().disable()
				// 由于使用Token,所以不需要Session
				.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and()
				// 验证Http请求
				.authorizeRequests()
				// 允许所有用户访问首页 与 登录
				.antMatchers(AUTH_WITHOUTLIST).permitAll()
				// 其它任何请求都要经过认证通过
				.anyRequest().authenticated().and()
				// 用户页面需要用户权限
				// 设置登出
				.logout().logoutSuccessHandler(authLogoutSuccessHandler).permitAll();
		// 添加JWT filter 在
		http.addFilterBefore(new JwtAuthenticationTokenFilter(tokenProvider), UsernamePasswordAuthenticationFilter.class);
	}


//判断是否有权限分三步 
后台security 已经对地址做了拦截了,请求头必须设置请求参数参数
1:判断token是否存在(security 已实现)
2:token是否有效(基于redis) 
3:访问API是否有权限

缓存结构:

[
  \"java.util.HashMap\",
  {
    \"userToken\": \"ISOFTSTONE.eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiI0MmRkMGJlZmQwNDg0MmMyODhiN2QxZjVkYTcwMWNjNiIsImF1dGgiOiJ1c2VyIiwiZXhwIjoxNjM1MjMyMzk4fQ.9VqMD0vyu-pe42moNd1QeNWP4KrBvvNYJKDQdQPDi_YKKXPG3l90dNn5wgK2rZXs471Pmeby-BdHPHd2-iNKfA\",
    \"userInfo\": [
      \"com.common.vo.CustomerVo\",
      {
        \"id\": \"42dd0befd04842c288b7d1f5da701cc6\",
        \"createTime\": [
          \"java.util.Date\",
          \"2021-06-10\"
        ],
        \"updateTime\": [
          \"java.util.Date\",
          \"2021-06-10\"
        ],
        \"deleted\": 0,
        \"phone\": \"13797004616\",
        \"password\": \"123456\",
        \"email\": \"sunlin@fiberhome.com\",
        \"status\": \"3\",
        \"isEnable\": \"1\",
        \"userType\": \"1\",
        \"roleId\": null,
        \"country\": null,
        \"provinces\": null,
        \"company\": null,
        \"jobs\": null,
        \"realName\": \"孙\",
        \"fiberhomeEmail\": null,
        \"department\": null,
        \"registerWay\": null,
        \"onlineTime\": null,
        \"expireDate\": null,
        \"registerIp\": null,
        \"language\": null,
        \"equipmentType\": null,
        \"accountType\": null,
        \"platformType\": null,
        \"companyType\": null,
        \"userdesc\": null,
        \"userid\": \"0210990342\",
        \"typeConfig\": null,
        \"isActive\": \"1\",
        \"postname\": \"副总经理\",
        \"did1\": \"701387\",
        \"dname1\": \"财务管理部\",
        \"did2\": null,
        \"dname2\": null,
        \"did3\": null,
        \"dname3\": null,
        \"did4\": null,
        \"dname4\": null,
        \"postid\": \"803711\"
      }
    ]
  }
]

接口实现返回:

x-token:ISOFTSTONE.eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiI0MmRkMGJlZmQwNDg0MmMyODhiN2QxZjVkYTcwMWNjNiIsImF1dGgiOiJ1c2VyIiwiZXhwIjoxNjM1MjMyNTMzfQ.4QzaY_ln-EVukG6Hnbx-mRl2nUB0Eu6jJxIN0KHigzLfqZH7aXt1aId0RhRvS-o5Vf7cVp5jd9cqpkQwfp724A

网站防篡改设备(篡改常识的系统最新章节)

请求其他接口访问,加入到请求头Headers里面即可。我们的api接口幂等就实现完成了。

给TA打赏
共{{data.count}}人
人已打赏
文章

压缩文件解密工具(绕过zip密码提取文件)

2022-4-12 10:39:26

文章

android时间选择控件大全(android常用控件大全)

2022-4-12 10:39:32

0 条回复 A文章作者 M管理员
    暂无讨论,说说你的看法吧
个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
搜索