SpringBoot+JWT@注解实现token验证springboot集成jwt实现token验证
1、引⼊jwt依赖
<!--jwt-->
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.9.0</version>
</dependency>
<dependency>
<groupId>com.auth0</groupId>
<artifactId>java-jwt</artifactId>
<version>3.9.0</version>
</dependency>
2、⾃定义两个注解
/**
* 忽略Token验证
*
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface IgnoreAuth {
boolean required() default true;
}
/**
* 登录⽤户信息
*
*/
@Target({ElementType.PARAMETER,ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface LoginUser {
boolean required() default true;
}
@Target:注解的作⽤⽬标
@Target(ElementType.TYPE)——接⼝、类、枚举、注解
@Target(ElementType.PARAMETER)——⽅法参数
@Target(ElementType.METHOD)——⽅法
3、定义⼀个⽤户实体类
/**
* ⽤户类
*
*/
@Data
@ApiModel(value="User对象", description="⽤户表")
public class User extends BaseEntity<User> {
private static final long serialVersionUID=1L;
@ApiModelProperty(value = "编号")
private String id;
@ApiModelProperty(value = "归属公司")
private String companyId;
@ApiModelProperty(value = "归属部门")
private String officeId;
@ApiModelProperty(value = "登录名")
private String loginName;
@ApiModelProperty(value = "密码")
private String password;
@ApiModelProperty(value = "⼯号")
private String no;
@ApiModelProperty(value = "姓名")
private String name;
@ApiModelProperty(value = "邮箱")
private String email;
@ApiModelProperty(value = "电话")
private String phone;
@ApiModelProperty(value = "⼿机")
private String mobile;
@ApiModelProperty(value = "⽤户类型")
private String userType;
@ApiModelProperty(value = "⽤户头像")
private String photo;
@ApiModelProperty(value = "最后登陆IP")
private String loginIp;
@ApiModelProperty(value = "最后登陆时间",example = "2019-11-22 00:00:00")
private Date loginDate;
@EnumFormat
@ApiModelProperty(value = "登录状态 : 0 正常,1 异常")
private UserLoginFlagEnum loginFlag;
@ApiModelProperty(value = "创建者")
private String createBy;
@ApiModelProperty(value = "创建时间",example = "2019-11-22 00:00:00")
private Date createDate;
@ApiModelProperty(value = "更新者")
private String updateBy;
@ApiModelProperty(value = "更新时间",example = "2019-11-22 00:00:00")
private Date updateDate;
@ApiModelProperty(value = "备注信息")
private String remarks;
@TableLogic
@ApiModelProperty(value = "删除标记")
private String delFlag;
@ApiModelProperty(value = "openid")
private String openid;
@Override
protected Serializable pkVal() {
return this.id;
}
}
4、⽣成token
@Service("TokenService")
public class TokenService {
public String getToken(User user) {
String token="";
token= ate().Id())// 将 user id 保存到 token ⾥⾯
.sign(Algorithm.Openid()));// 以 OpenId 作为 token 的密钥
return token;
}
}
5、设置
@Component
public class AuthorizationInterceptor implements HandlerInterceptor {
@Autowired
IUserService userService;
public static final String LOGIN_USER_KEY = "LOGIN_USER_KEY";
@Override
public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object object) throws Exception { //⽀持跨域请求
httpServletResponse.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");
httpServletResponse.setHeader("Access-Control-Max-Age", "3600");
httpServletResponse.setHeader("Access-Control-Allow-Credentials", "true");
httpServletResponse.setHeader("Access-Control-Allow-Headers", "x-requested-with,X-Nideshop-Token,X-URL-PATH");
httpServletResponse.setHeader("Access-Control-Allow-Origin", Header("Origin"));
String token = Header("token");// 从 http 请求头中取出 token
// 如果不是映射到⽅法直接通过
if(!(object instanceof HandlerMethod)){
return true;
}
HandlerMethod handlerMethod=(HandlerMethod)object;
Method Method();
//检查是否有IgnoreAuth注释,有则跳过认证
if (method.isAnnotationPresent(IgnoreAuth.class)) {
IgnoreAuth passToken = Annotation(IgnoreAuth.class);
if (quired()) {
return true;
}
}
//检查有没有需要⽤户权限的注解
if (method.isAnnotationPresent(LoginUser.class)) {
LoginUser userLoginToken = Annotation(LoginUser.class);
if (userLoginToken !=null) {
// 执⾏认证
if (token == null) {
throw new RuntimeException("⽆token,请重新登录");
}
// 获取 token 中的 user id
String userId;
try {
userId = JWT.decode(token).getAudience().get(0);
} catch (JWTDecodeException j) {
throw new RuntimeException("401");
}
//设置userId到request⾥,后续根据userId,获取⽤户信息
httpServletRequest.setAttribute(LOGIN_USER_KEY, userId);
User user = ById(userId);
if (user == null) {
throw new RuntimeException("⽤户不存在,请重新登录");
}
// 验证 token
JWTVerifier jwtVerifier = quire(Algorithm.Openid())).build();
try {
jwtVerifier.verify(token);
} catch (JWTVerificationException e) {
throw new RuntimeException("401");
}
return true;
}spring ioc注解
}
return true;
}
@Override
public void postHandle(HttpServletRequest httpServletRequest,
HttpServletResponse httpServletResponse,
Object o, ModelAndView modelAndView) throws Exception {
}
@Override
public void afterCompletion(HttpServletRequest httpServletRequest,
HttpServletResponse httpServletResponse,
Object o, Exception e) throws Exception {
}
}
6、配置
在配置类上添加了注解@Configuration,标明了该类是⼀个配置类并且会将该类作为⼀个SpringBean添加到IOC容器内@Configuration
public class InterceptorConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(authenticationInterceptor())
.addPathPatterns("/**");
}
@Bean
public AuthenticationInterceptor authenticationInterceptor() {
return new AuthenticationInterceptor();
}
}
7、token验证流程
1、⽤户登录是⽣成token
2、从http请求头中取出token
3、判断是否映射到⽅法
4、检查是否有@IgnoreAuth注释,有则跳过认证
5、检查是否有⽤户登录的注解,有则需要取出并验证
6、认证通过则可以访问
public class JWTUtil {
public static final String SECRET_KEY = "123456"; //秘钥
public static final long TOKEN_EXPIRE_TIME = 5 * 60 * 1000; //token过期时间
public static final long REFRESH_TOKEN_EXPIRE_TIME = 10 * 60 * 1000; //refreshToken过期时间
private static final String ISSUER = "issuer"; //签发⼈
/**
* ⽣成签名
*/
public static String generateToken(String username){
Date now = new Date();
Algorithm algorithm = Algorithm.HMAC256(SECRET_KEY); //算法
String token = ate()
.withIssuer(ISSUER) //签发⼈
.withIssuedAt(now) //签发时间
.withExpiresAt(new Time() + TOKEN_EXPIRE_TIME)) //过期时间
.withClaim("username", username) //保存⾝份标识
.sign(algorithm);
return token;
}
/**
* 验证token
*/
public static boolean verify(String token){
try {
Algorithm algorithm = Algorithm.HMAC256(SECRET_KEY); //算法 JWTVerifier verifier = quire(algorithm)
.withIssuer(ISSUER)
.build();
verifier.verify(token);
return true;
} catch (Exception ex){
ex.printStackTrace();
}
return false;
}
/**
* 从token获取username
*/
public static String getUsername(String token){
try{
return JWT.decode(token).getClaim("username").asString();
}catch(Exception ex){
ex.printStackTrace();
}
return "";
}
}
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论