为什么调用接口header要加sign和time
时间: 2023-11-27 19:05:39 浏览: 19
调用接口时,添加sign和time这两个参数主要是为了实现接口的安全性和防止非法访问。
首先,sign参数用于对请求进行签名,可以确保请求的完整性和合法性。签名通常是通过对请求参数进行加密或者哈希计算得到的,接收方可以根据同样的算法验证签名是否匹配,从而确定请求是否被篡改。
其次,time参数用于防止重放攻击。重放攻击是指攻击者截获合法请求后,再次发送相同的请求来进行欺骗或者恶意操作。通过在每个请求中添加时间戳参数,可以确保每个请求都是唯一的,避免被重放。
综上所述,添加sign和time这两个参数可以提高接口的安全性,防止非法访问和重放攻击。
相关问题
Spring Security如何在接口中登录方式
Spring Security提供了多种方式来实现接口中的登录,其中常见的方式是使用token认证。以下是一个简单的示例:
1. 配置Spring Security
在Spring Security的配置文件中,需要配置一个TokenAuthenticationFilter来处理token认证。具体如下:
```java
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private JwtTokenProvider jwtTokenProvider;
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable()
.authorizeRequests()
.antMatchers("/login").permitAll()
.anyRequest().authenticated()
.and()
.apply(new JwtConfigurer(jwtTokenProvider));
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
@Bean
public JwtTokenProvider jwtTokenProvider() {
return new JwtTokenProvider();
}
@Bean
public TokenAuthenticationFilter jwtAuthenticationTokenFilter() throws Exception {
return new TokenAuthenticationFilter();
}
}
```
2. 创建TokenAuthenticationFilter
TokenAuthenticationFilter是一个过滤器,用于在请求头中读取并验证token。具体如下:
```java
public class TokenAuthenticationFilter extends OncePerRequestFilter {
@Autowired
private JwtTokenProvider jwtTokenProvider;
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
String token = jwtTokenProvider.resolveToken(request);
if (token != null && jwtTokenProvider.validateToken(token)) {
Authentication auth = jwtTokenProvider.getAuthentication(token);
if (auth != null) {
SecurityContextHolder.getContext().setAuthentication(auth);
}
}
filterChain.doFilter(request, response);
}
}
```
3. 创建JwtTokenProvider
JwtTokenProvider用于生成和验证token。具体如下:
```java
public class JwtTokenProvider {
private static final String SECRET_KEY = "secret_key";
private static final long EXPIRATION_TIME = 864_000_000; // 10 days
private static final String TOKEN_PREFIX = "Bearer ";
private static final String HEADER_STRING = "Authorization";
public String createToken(String username) {
Claims claims = Jwts.claims().setSubject(username);
Date now = new Date();
Date validity = new Date(now.getTime() + EXPIRATION_TIME);
return Jwts.builder()
.setClaims(claims)
.setIssuedAt(now)
.setExpiration(validity)
.signWith(SignatureAlgorithm.HS256, SECRET_KEY)
.compact();
}
public Authentication getAuthentication(String token) {
String username = getUsername(token);
User user = userService.loadUserByUsername(username);
return new UsernamePasswordAuthenticationToken(user, "", user.getAuthorities());
}
public String getUsername(String token) {
return Jwts.parser().setSigningKey(SECRET_KEY).parseClaimsJws(token).getBody().getSubject();
}
public boolean validateToken(String token) {
try {
Jwts.parser().setSigningKey(SECRET_KEY).parseClaimsJws(token);
return true;
} catch (SignatureException | MalformedJwtException | ExpiredJwtException | UnsupportedJwtException | IllegalArgumentException ex) {
return false;
}
}
public String resolveToken(HttpServletRequest request) {
String bearerToken = request.getHeader(HEADER_STRING);
if (bearerToken != null && bearerToken.startsWith(TOKEN_PREFIX)) {
return bearerToken.substring(TOKEN_PREFIX.length());
}
return null;
}
}
```
4. 创建登录接口
在登录接口中,需要调用JwtTokenProvider.createToken方法生成token,并将token返回给客户端。具体如下:
```java
@RestController
public class LoginController {
@Autowired
private JwtTokenProvider jwtTokenProvider;
@PostMapping("/login")
public ResponseEntity<?> login(@RequestBody LoginRequest loginRequest) {
Authentication authentication = authenticationManager.authenticate(
new UsernamePasswordAuthenticationToken(
loginRequest.getUsername(),
loginRequest.getPassword()
)
);
SecurityContextHolder.getContext().setAuthentication(authentication);
String token = jwtTokenProvider.createToken(loginRequest.getUsername());
return ResponseEntity.ok(new JwtResponse(token));
}
}
```
5. 测试接口
使用Postman等工具发送请求,将生成的token放入请求头中,即可访问需要登录后才能访问的接口。
var url = '/api/pc/ca/manager/member/modify/applyInfo/page'; //1.dologin var bsmpUrl = pm.environment.get("server.url.bsmp"); var username = pm.environment.get("bsmp.login.pc.username"); var password = pm.environment.get("bsmp.login.pc.password"); var salt = pm.environment.get("bsmp.login.pc.salt"); var orgId = pm.environment.get("bsmp.login.pc.orgId"); var orgLevel = pm.environment.get("bsmp.login.pc.orgLevel"); let echoPostRequest = { url: 'http://' + bsmpUrl + '/api/pc/proxy/login', method: 'POST', header: [ "Content-Type: application/json; charset=UTF-8" ], body: { mode: 'raw', raw: '{\"username\":\"'+username+'\",\"password\":\"'+password+'\",\"salt\":\"'+salt+'\"}' } }; let echoGetRequest = { url: 'http://' + bsmpUrl + '/api/pc/proxy/complete' + '?' + 'orgId='+ orgId + '&' + 'orgLevel=' + orgLevel + '&' + 'time=' + '0.366126544927456', method: 'GET' }; pm.sendRequest(echoPostRequest, function (err, res) { console.log("loginRsp:" + res.json()); console.log("token:" + res.json().data) //2.doSign var token = res.json().data; var str = token + url pm.globals.set("temp", str); var sign = CryptoJS.MD5(str).toString(); pm.globals.set("token",token ); pm.globals.set("sign", sign); }); pm.sendRequest(echoGetRequest, function (err, res) { console.log("res:" + res.json()); }); 如何将此代码中的两个接口,按照顺序调用
可以使用回调函数或Promise对象来保证这两个接口按照顺序调用。
使用回调函数的方式,可以在第一个请求的回调函数中调用第二个请求。例如:
```
var url = '/api/pc/ca/manager/member/modify/applyInfo/page';
var bsmpUrl = pm.environment.get("server.url.bsmp");
var username = pm.environment.get("bsmp.login.pc.username");
var password = pm.environment.get("bsmp.login.pc.password");
var salt = pm.environment.get("bsmp.login.pc.salt");
var orgId = pm.environment.get("bsmp.login.pc.orgId");
var orgLevel = pm.environment.get("bsmp.login.pc.orgLevel");
function doLogin(callback) {
let echoPostRequest = {
url: 'http://' + bsmpUrl + '/api/pc/proxy/login',
method: 'POST',
header: [
"Content-Type: application/json; charset=UTF-8"
],
body: {
mode: 'raw',
raw: '{\"username\":\"'+username+'\",\"password\":\"'+password+'\",\"salt\":\"'+salt+'\"}'
}
};
pm.sendRequest(echoPostRequest, function (err, res) {
console.log("loginRsp:" + res.json());
console.log("token:" + res.json().data);
var token = res.json().data;
var str = token + url;
pm.globals.set("temp", str);
var sign = CryptoJS.MD5(str).toString();
pm.globals.set("token",token );
pm.globals.set("sign", sign);
callback();
});
}
function doSign() {
var token = pm.globals.get("token");
var sign = pm.globals.get("sign");
let echoGetRequest = {
url: 'http://' + bsmpUrl + '/api/pc/proxy/complete' + '?' + 'orgId='+ orgId + '&' + 'orgLevel=' + orgLevel + '&' + 'time=' + '0.366126544927456' + '&' + 'token=' + token + '&' + 'sign=' + sign,
method: 'GET'
};
pm.sendRequest(echoGetRequest, function (err, res) {
console.log("res:" + res.json());
});
}
doLogin(function() {
doSign();
});
```
使用Promise对象的方式,可以通过链式调用then方法来保证接口按照指定的顺序调用。例如:
```
var url = '/api/pc/ca/manager/member/modify/applyInfo/page';
var bsmpUrl = pm.environment.get("server.url.bsmp");
var username = pm.environment.get("bsmp.login.pc.username");
var password = pm.environment.get("bsmp.login.pc.password");
var salt = pm.environment.get("bsmp.login.pc.salt");
var orgId = pm.environment.get("bsmp.login.pc.orgId");
var orgLevel = pm.environment.get("bsmp.login.pc.orgLevel");
function doLogin() {
return new Promise(function(resolve, reject) {
let echoPostRequest = {
url: 'http://' + bsmpUrl + '/api/pc/proxy/login',
method: 'POST',
header: [
"Content-Type: application/json; charset=UTF-8"
],
body: {
mode: 'raw',
raw: '{\"username\":\"'+username+'\",\"password\":\"'+password+'\",\"salt\":\"'+salt+'\"}'
}
};
pm.sendRequest(echoPostRequest, function (err, res) {
console.log("loginRsp:" + res.json());
console.log("token:" + res.json().data);
var token = res.json().data;
var str = token + url;
pm.globals.set("temp", str);
var sign = CryptoJS.MD5(str).toString();
pm.globals.set("token",token );
pm.globals.set("sign", sign);
resolve();
});
});
}
function doSign() {
var token = pm.globals.get("token");
var sign = pm.globals.get("sign");
let echoGetRequest = {
url: 'http://' + bsmpUrl + '/api/pc/proxy/complete' + '?' + 'orgId='+ orgId + '&' + 'orgLevel=' + orgLevel + '&' + 'time=' + '0.366126544927456' + '&' + 'token=' + token + '&' + 'sign=' + sign,
method: 'GET'
};
pm.sendRequest(echoGetRequest, function (err, res) {
console.log("res:" + res.json());
});
}
doLogin()
.then(function() {
doSign();
});
```