1500字范文,内容丰富有趣,写作好帮手!
1500字范文 > jwt token 附加用户信息_SpringBoot+JWT实现token验证并将用户信息存储到@注解内

jwt token 附加用户信息_SpringBoot+JWT实现token验证并将用户信息存储到@注解内

时间:2021-02-26 11:39:19

相关推荐

jwt token 附加用户信息_SpringBoot+JWT实现token验证并将用户信息存储到@注解内

springboot集成jwt实现token验证

1、引入jwt依赖

io.jsonwebtoken

jjwt

0.9.0

com.auth0

java-jwt

3.9.0

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 {

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 = "-11-22 00:00:00")

private Date loginDate;

@EnumFormat

@ApiModelProperty(value = "登录状态 : 0 正常,1 异常")

private UserLoginFlagEnum loginFlag;

@ApiModelProperty(value = "创建者")

private String createBy;

@ApiModelProperty(value = "创建时间",example = "-11-22 00:00:00")

private Date createDate;

@ApiModelProperty(value = "更新者")

private String updateBy;

@ApiModelProperty(value = "更新时间",example = "-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= JWT.create().withAudience(user.getId())// 将 user id 保存到 token 里面

.sign(Algorithm.HMAC256(user.getOpenid()));// 以 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", httpServletRequest.getHeader("Origin"));

String token = httpServletRequest.getHeader("token");// 从 http 请求头中取出 token

// 如果不是映射到方法直接通过

if(!(object instanceof HandlerMethod)){

return true;

}

HandlerMethod handlerMethod=(HandlerMethod)object;

Method method=handlerMethod.getMethod();

//检查是否有IgnoreAuth注释,有则跳过认证

if (method.isAnnotationPresent(IgnoreAuth.class)) {

IgnoreAuth passToken = method.getAnnotation(IgnoreAuth.class);

if (passToken.required()) {

return true;

}

}

//检查有没有需要用户权限的注解

if (method.isAnnotationPresent(LoginUser.class)) {

LoginUser userLoginToken = method.getAnnotation(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 = userService.getById(userId);

if (user == null) {

throw new RuntimeException("用户不存在,请重新登录");

}

// 验证 token

JWTVerifier jwtVerifier = JWT.require(Algorithm.HMAC256(user.getOpenid())).build();

try {

jwtVerifier.verify(token);

} catch (JWTVerificationException e) {

throw new RuntimeException("401");

}

return true;

}

}

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、认证通过则可以访问

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。