JWT简介
Json web token (JWT), 是为了在网络应用环境间传递声明而执行的一种基于JSON的开放标准((RFC 7519).定义了一种简洁的,自包含的方法用于通信双方之间以JSON对象的形式安全的传递信息。因为数字签名的存在,这些信息是可信的,JWT可以使用HMAC算法或者是RSA的公私秘钥对进行签名。
JWT 格式组成:头部、负载、签名
header payload signature
头部:主要是描述签名算法
负载:主要描述是加密对象的信息,如用户的id等,也可以加些规范里面的东西,如 iss 签发者,exp 过期时间,sub 面向的用户
签名:主要是把前面两部分进行加密,防止别人拿到 token 进行 base 解密后篡改 token
SpringBoot和JWT的集成
- pom文件引入依赖
<dependency>
<groupId>com.auth0groupId>
<artifactId>java-jwtartifactId>
<version>3.4.0version>
dependency>
- 实体类SysUser.java
@Data
@Accessors(chain = true)
@AllArgsConstructor
@NoArgsConstructor
@TableName("sys_user")
public class SysUser implements Serializable {
private static final long serialVersionUID = 798147584464604992L;
@TableId(type = IdType.AUTO)
private Integer userId;
/**
* 用户名
*/
private String username;
/**
* 密码
*/
private String password;
private Date createTime;
private Date updateTime;
/**
* 1:删除,0:正常
*/
private Integer isDelete;
}
- Service接口
public interface SysUserService {
SysUser login(SysUserReq userReq);
SysUserResp info(int userId);
}
- Impl:
@Slf4j
@Service("sysUserService")
public class SysUserServiceImpl implements SysUserService {
@Autowired
private SysUserDao sysUserDao;
@Autowired
private SysUserRoleDao sysUserRoleDao;
@Autowired
private SysRoleDao sysRoleDao;
@Override
public SysUser login(SysUserReq user) {
String password = user.getPassword();
user.setPassword(MD5Tools.string2MD5(password));
SysUser sysUser = new SysUser();
BeanUtils.copyProperties(user, sysUser);
QueryWrapper queryWrapper = new QueryWrapper<>(sysUser);
SysUser user1 = sysUserDao.selectOne(queryWrapper.eq("username", sysUser.getUsername()).eq("password", sysUser.getPassword()));
return user1;
}
@Override
public SysUserResp info(int userId) {
SysUser sysUser = sysUserDao.selectById(userId);
if (sysUser != null) {
List userRoles = sysUserRoleDao.selectList(new QueryWrapper().eq("user_id", userId));
if (userRoles != null && userRoles.size() > 0) {
SysUserResp sysUserResp = new SysUserResp();
sysUserResp.setName(sysUser.getUsername());
sysUserResp.setAvatar("https://wpimg.wallstcn.com/f778738c-e4f8-4870-b634-56703b4acafe.gif");
List roles = new ArrayList<>();
for (SysUserRole userRole : userRoles) {
SysRole sysRole = sysRoleDao.selectById(userRole.getRoleId());
if (sysRole != null) {
roles.add(sysRole.getRoleName());
}
}
sysUserResp.setRoles(roles);
return sysUserResp;
}
}
return null;
}
}
- controller:
@Slf4j
@RestController
@RequestMapping("sysUser")
public class SysUserController {
/**
* 服务对象
*/
@Autowired
private SysUserService sysUserService;
@PostMapping("login")
public JsonResult login(@Valid @RequestBody SysUserReq userReq, HttpServletRequest request, HttpServletResponse response) {
try {
String randomText = (String) request.getSession().getAttribute("verifyCode");
if (!userReq.getRandomText().equalsIgnoreCase(randomText)) {
return JsonResultUtil.getErrorJson("验证码错误!");
}
SysUser user1 = sysUserService.login(userReq);
if (user1 == null) {
return JsonResultUtil.getErrorJson("用户名或密码错误");
} else {
//生成token
String token = TokenUtil.sign(user1);
TokenResp tokenResp = new TokenResp();
tokenResp.setToken(token);
tokenResp.setUserId(user1.getUserId());
return JsonResultUtil.getSuccessJson("登录成功", tokenResp);
}
} catch (Exception e) {
e.printStackTrace();
}
return JsonResultUtil.getErrorJson("登录失败");
}
@PostMapping("info")
public JsonResult info(@Valid @RequestBody TokenResp tokenResp, HttpServletRequest request, HttpServletResponse response) {
try {
SysUserResp sysUserResp = sysUserService.info(tokenResp.getUserId());
if (sysUserResp != null) {
return JsonResultUtil.getSuccessJson("获取用户信息成功", sysUserResp);
}
} catch (Exception e) {
e.printStackTrace();
}
return JsonResultUtil.getErrorJson("获取用户信息失败");
}
}
- token工具类:
public class TokenUtil {
private static final long EXPIRE_TIME= 15*60*1000;
private static final String TOKEN_SECRET="token123"; //密钥盐
/**
* 签名生成
* @param user
* @return
*/
public static String sign(SysUser user){
String token = null;
try {
Date expiresAt = new Date(System.currentTimeMillis() EXPIRE_TIME);
token = JWT.create()
.withIssuer("auth0")
.withClaim("username", user.getUsername())
.withExpiresAt(expiresAt)
// 使用了HMAC256加密算法。
.sign(Algorithm.HMAC256(TOKEN_SECRET));
} catch (Exception e){
e.printStackTrace();
}
return token;
}
/**
* 签名验证
* @param token
* @return
*/
public static boolean verify(String token){
try {
JWTVerifier verifier = JWT.require(Algorithm.HMAC256(TOKEN_SECRET)).withIssuer("auth0").build();
DecodedJWT jwt = verifier.verify(token);
System.out.println("认证通过:");
System.out.println("issuer: " jwt.getIssuer());
System.out.println("username: " jwt.getClaim("username").asString());
System.out.println("过期时间: " jwt.getExpiresAt());
return true;
} catch (Exception e){
return false;
}
}
}
- 拦截器:
@Component
public class TokenInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
if (request.getMethod().equals("OPTIONS")) {
response.setStatus(HttpServletResponse.SC_OK);
return true;
}
response.setCharacterEncoding("utf-8");
String token = request.getHeader("token");
if (token != null) {
boolean result = TokenUtil.verify(token);
if (result) {
System.out.println("通过拦截器");
return true;
}
}
response.setCharacterEncoding("UTF-8");
response.setContentType("application/json; charset=utf-8");
PrintWriter out = null;
try {
JsonResult jsonResult = new JsonResult();
jsonResult.setCode(401);
jsonResult.setMessage("invalid token");
response.getWriter().append(JSON.toJSONString(jsonResult));
System.out.println("认证失败,未通过拦截器");
// response.getWriter().write("50000");
} catch (Exception e) {
e.printStackTrace();
response.sendError(500);
return false;
}
return false;
}
}
- 配置拦截器:
/**
* 拦截器配置
*/
@Configuration
public class IntercepterConfig implements WebMvcConfigurer {
private TokenInterceptor tokenInterceptor;
//构造方法
public IntercepterConfig(TokenInterceptor tokenInterceptor){
this.tokenInterceptor = tokenInterceptor;
}
@Override
public void addInterceptors(InterceptorRegistry registry){
List excludePath = new ArrayList<>();
excludePath.add("/sysUser/login"); //注册
excludePath.add("/checkcode/getVerifyCode"); //注册
registry.addInterceptor(tokenInterceptor)
.addPathPatterns("/**")
.excludePathPatterns(excludePath);
WebMvcConfigurer.super.addInterceptors(registry);
}
}
使用postMan测试
- 获取验证码
- 提交正确的用户名,密码和验证码,验证通过,可以获取到token信息。
- 通过token获取用户信息
- 获取用户信息不加token返回验证失败
内容出处:,
声明:本网站所收集的部分公开资料来源于互联网,转载的目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。如果您发现网站上有侵犯您的知识产权的作品,请与我们取得联系,我们会及时修改或删除。文章链接:http://www.yixao.com/procedure/12366.html