springboot+jwt完成登录认证

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测试

  • 获取验证码
springboot jwt完成登录认证
  • 提交正确的用户名,密码和验证码,验证通过,可以获取到token信息。
springboot jwt完成登录认证
  • 通过token获取用户信息
springboot jwt完成登录认证
  • 获取用户信息不加token返回验证失败
springboot jwt完成登录认证

内容出处:,

声明:本网站所收集的部分公开资料来源于互联网,转载的目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。如果您发现网站上有侵犯您的知识产权的作品,请与我们取得联系,我们会及时修改或删除。文章链接:http://www.yixao.com/procedure/12366.html

发表评论

登录后才能评论