springboot 写一个生成token的接口,其它接口需要访问必须戴上这个token
时间: 2023-07-16 14:17:39 浏览: 110
可以使用JWT(JSON Web Token)生成token,并使用拦截器对需要访问的接口进行拦截验证token。
首先,添加依赖:
```xml
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.9.1</version>
</dependency>
```
然后,编写生成token的接口:
```java
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import java.util.Date;
@RestController
public class TokenController {
// 生成token接口
@PostMapping("/token")
public String generateToken(@RequestParam("username") String username) {
// 设置过期时间为1小时
Date expiration = new Date(System.currentTimeMillis() + 60 * 60 * 1000);
// 生成token
String token = Jwts.builder()
.setSubject(username)
.setExpiration(expiration)
.signWith(SignatureAlgorithm.HS256, "secret-key")
.compact();
return token;
}
}
```
其中,`generateToken` 方法接收用户名参数,设置token过期时间为1小时,然后使用 `Jwts` 类生成token,并使用 `HS256` 算法进行签名。这里的 `secret-key` 为签名所使用的密钥,可以根据具体情况进行修改。
最后,编写拦截器:
```java
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@Component
public class TokenInterceptor implements HandlerInterceptor {
// 拦截器的前置处理
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
// 从请求头中获取token
String token = request.getHeader("token");
if (token == null || token.isEmpty()) {
// token为空,返回401未授权错误
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
return false;
}
// 验证token
try {
Claims claims = Jwts.parser().setSigningKey("secret-key").parseClaimsJws(token).getBody();
// 将用户名存入request中,方便后续操作
request.setAttribute("username", claims.getSubject());
return true;
} catch (Exception e) {
// token验证失败,返回401未授权错误
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
return false;
}
}
}
```
在拦截器中,从请求头中获取token,然后使用 `Jwts` 类验证token是否正确。如果验证通过,将用户名存入request中,方便后续操作。如果验证失败,返回401未授权错误。
最后,在需要验证token的接口上添加 `@PreAuthorize` 注解:
```java
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class HelloController {
// 需要验证token的接口
@GetMapping("/hello")
@PreAuthorize("hasRole('USER')")
public String hello() {
return "hello, " + SecurityContextHolder.getContext().getAuthentication().getName();
}
}
```
在这个示例中,使用 `@PreAuthorize("hasRole('USER')")` 注解表示只有具有 `USER` 角色的用户才能访问该接口。在接口中使用 `SecurityContextHolder.getContext().getAuthentication().getName()` 可以获取当前用户的用户名。
最后,在启动类上添加拦截器配置:
```java
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@SpringBootApplication
public class Application implements WebMvcConfigurer {
@Autowired
private TokenInterceptor tokenInterceptor;
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
// 注册拦截器
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(tokenInterceptor).addPathPatterns("/**").excludePathPatterns("/token");
}
}
```
在这个示例中,使用 `addInterceptors` 方法注册拦截器,并将拦截器应用到所有路径上,但排除生成token的接口 `"/token"`。
阅读全文