SpringBoot + JWT实现Token验证


需求

  • SpringBoot项目集成JWT,实现Token验证,保存用户登录状态。
  • 项目已上传到github,欢迎参考~
    • https://github.com/ABCVBNM/jwt_demo.git

实现

1. 添加依赖

这里选择的是jwtk/jjwt(因为看github上的Java_JWT项目,该项目维护最及时,星星最多)

	<dependency>
        <groupId>io.jsonwebtoken</groupId>
        <artifactId>jjwt-api</artifactId>
        <version>0.11.2</version>
    </dependency>
    <dependency>
        <groupId>io.jsonwebtoken</groupId>
        <artifactId>jjwt-impl</artifactId>
        <version>0.11.2</version>
        <scope>runtime</scope>
    </dependency>
    <dependency>
        <groupId>io.jsonwebtoken</groupId>
        <artifactId>jjwt-jackson</artifactId> <!-- or jjwt-gson if Gson is preferred -->
        <version>0.11.2</version>
        <scope>runtime</scope>
    </dependency>
    <!-- Uncomment this next dependency if you are using JDK 10 or earlier and you also want to use
         RSASSA-PSS (PS256, PS384, PS512) algorithms.  JDK 11 or later does not require it for those algorithms:-->
    <dependency>
        <groupId>org.bouncycastle</groupId>
        <artifactId>bcprov-jdk15on</artifactId>
        <version>1.60</version>
        <scope>runtime</scope>
    </dependency>`
2. 编写编写TokenUtils类
1. 添加生成Token方法getToken
2. 添加解析Token方法parseToken
3. 添加验证Token方法verifyToken

因为要适配的项目业务不多,所以将用户信息保存在静态变量中,实现缓存的效果,每次解析Token都会进行对比。

	      public String getToken(User user) {

		        // String jws = Jwts.builder().setSubject(user.getUserName()).setExpiration(new Date(System.currentTimeMillis() + 3600 * 24 * 1000)).signWith(key).compact();
		        user.setPassWord("");
				// user.setUserName("");
		        Claims claims = Jwts.claims();
		        claims.put("user", user);
		        userName = user.getUserName();
		        admin = user.getAdmin();
		        warehouseName = user.getWarehouseName();
		        String jws = Jwts.builder().setClaims(claims).setExpiration(new Date(System.currentTimeMillis() + 3600 * 24 * 1000)).signWith(key).compact();
		        return jws;
		    }
		
		    public HashMap parseToken(String token) {
		        try {
		            LinkedHashMap userMap = (LinkedHashMap) Jwts.parserBuilder().setSigningKey(key).build().parseClaimsJws(token).getBody().get("user");
		            return userMap;
		        } catch (ExpiredJwtException e) {
		            e.printStackTrace();
		        } catch (UnsupportedJwtException e) {
		            e.printStackTrace();
		        } catch (MalformedJwtException e) {
		            e.printStackTrace();
		        } catch (SignatureException e) {
		            e.printStackTrace();
		        } catch (IllegalArgumentException e) {
		            e.printStackTrace();
		        }
		        return null;
		    }
		
			// 拦截器用
		    public boolean verifyToken(String token) {
		        HashMap map = parseToken(token);
		        if (map == null) return false;
		        if (map.get("userName").equals(userName) || map.get("admin").equals(admin) || map.get("warehouseName").equals(warehouseName))
		            return true;
		        return false;
		    }  
3. 添加过滤器

拦截请求,调用Tokenutil进行token校验,校验失败返回401。
SpringBoot中编写过滤器,只需要实现HandlerInterceptor接口即可。

	@Component
	public class LoginHandlerInterceptor implements HandlerInterceptor {
	
	    @Resource(name = "tokenUtilService")
	    TokenUtilService tokenUtilService;
	
	    @Override
	    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
	        String token = request.getHeader("L_Token");
	        if (token == null || !tokenUtilService.verifyToken(token)) {
	            response.setStatus(401);
	            response.getWriter().print("无效的Token,请重新登录!");
	            response.getWriter().flush();
	            return false;
	        }
	        return true;
	    }
	
	//    todo: print logs
	    @Override
	    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
	
	    }
	
	    @Override
	    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
	
	    }
	}
4. 添加配置类,配置过滤器

excludePath中添加需要放行的请求,这里边只添加了login

	@Configuration
	public class LoginInterceptConf implements WebMvcConfigurer {
	
	    @Resource
	    LoginHandlerInterceptor loginHandlerInterceptor;
	
	    @Override
	    public void addInterceptors(InterceptorRegistry registry) {
	        registry.addInterceptor(loginHandlerInterceptor).excludePathPatterns("/login");
	    }
	}
5. 编写登陆类
1. 实现登录接口
2. 实现根据Token获取用户信息接口


	@Controller
	public class Login {
	    public static String userName = "li";
	    public static String passWord = "lei";
	    public static String admin = "1";
	
	    @Resource(name = "tokenUtilService")
	    TokenUtilService tokenUtilService;
	
	    @RequestMapping(method = RequestMethod.POST, value = "/login")
	    @ResponseBody
	    public String login(@RequestBody User user) {
	        Result result = new Result();
	        if (user.getUserName().equals(userName) && user.getPassWord().equals(passWord)) {
	            user.setAdmin(admin);
	            user.setWarehouseName("深圳实验室");
	            result.setMsg("success!");
	            result.setCode("200");
	            result.setToken(tokenUtilService.getToken(user));
	        } else {
	            result.setMsg("fail");
	            result.setCode("404");
	        }
	        return JSON.toJSONString(result);
	    }
	
	    @RequestMapping(method = RequestMethod.POST, value = "/getUserInfo")
	    @ResponseBody
	    public HashMap getUserInfoByToken(String token) {
	        HashMap map = tokenUtilService.parseToken(token);
	        return map;
	    }
	
	}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 可以参考下面的代码实现 Springboot 使用 JWT 实现 Token 登录验证:@Configuration public class SecurityConfig extends WebSecurityConfigurerAdapter { // ... @Override protected void configure(HttpSecurity http) throws Exception { http.csrf().disable() .authorizeRequests() .antMatchers("/api/**").authenticated() .and() .addFilter(new JWTAuthenticationFilter(authenticationManager())) .addFilter(new JWTAuthorizationFilter(authenticationManager())); } } ### 回答2: Spring Boot是一个开发框架,可用于构建独立的、基于Spring的应用程序。JWT(Json Web Token)是一种用于认证和授权的开放标准,它将用户信息加密在令牌中。 下面是使用Spring Boot和JWT实现Token登录验证的代码示例: 1. 首先,需要导入所需的依赖项。在pom.xml文件中添加以下依赖: ```xml <dependency> <groupId>io.jsonwebtoken</groupId> <artifactId>jjwt-api</artifactId> <version>0.11.2</version> </dependency> <dependency> <groupId>io.jsonwebtoken</groupId> <artifactId>jjwt-impl</artifactId> <version>0.11.2</version> <scope>runtime</scope> </dependency> <dependency> <groupId>io.jsonwebtoken</groupId> <artifactId>jjwt-jackson</artifactId> <version>0.11.2</version> <scope>runtime</scope> </dependency> ``` 2. 创建一个JWT工具类,用于生成和解析JWT的方法: ```java import io.jsonwebtoken.Claims; import io.jsonwebtoken.Jwts; import io.jsonwebtoken.SignatureAlgorithm; import java.util.Date; public class JwtUtil { private static final String SECRET_KEY = "your_secret_key"; private static final long EXPIRATION_TIME = 86400000; // 24小时 public static String generateToken(String username) { Date now = new Date(); Date expirationTime = new Date(now.getTime() + EXPIRATION_TIME); return Jwts.builder() .setSubject(username) .setIssuedAt(now) .setExpiration(expirationTime) .signWith(SignatureAlgorithm.HS512, SECRET_KEY) .compact(); } public static String getUsernameFromToken(String token) { Claims claims = Jwts.parser() .setSigningKey(SECRET_KEY) .parseClaimsJws(token) .getBody(); return claims.getSubject(); } public static boolean validateToken(String token) { try { Jwts.parser().setSigningKey(SECRET_KEY).parseClaimsJws(token); return true; } catch (Exception e) { return false; } } } ``` 3. 创建一个控制器,包含登录和验证方法: ```java import org.springframework.web.bind.annotation.*; @RestController @RequestMapping("/api") public class AuthController { @PostMapping("/login") public ResponseEntity<?> login(@RequestBody UserCredentials credentials) { // 检查用户凭据并生成令牌 if (credentials.getUsername().equals("admin") && credentials.getPassword().equals("admin123")) { String token = JwtUtil.generateToken(credentials.getUsername()); return ResponseEntity.ok(new AuthResponse(token)); } else { return ResponseEntity.status(HttpStatus.UNAUTHORIZED).build(); } } @GetMapping("/protected") public ResponseEntity<?> protectedResource(@RequestHeader("Authorization") String token) { // 验证令牌并提供受保护的资源 if (JwtUtil.validateToken(token)) { return ResponseEntity.ok("Protected resource accessed successfully"); } else { return ResponseEntity.status(HttpStatus.UNAUTHORIZED).build(); } } } ``` 4. 定义用户凭据模型类: ```java public class UserCredentials { private String username; private String password; // getter和setter方法 } ``` 5. 定义认证响应模型类: ```java public class AuthResponse { private String token; // 构造函数和getter方法 } ``` 上述代码示例实现了使用JWT进行Token登录验证的功能。用户通过登录接口提供正确的凭据后,将获得一个JWT令牌。然后,可以使用此令牌访问受保护的资源,该资源通过令牌进行验证。如果验证成功,则允许访问,否则返回未授权的HTTP状态码。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值