jwt实现 登陆验证

200 阅读3分钟

JWT(JSON Web Token)是一种用于安全地在用户和服务器之间传递信息的机制,常用于身份验证和信息交换。

JWT的工作流程

  1. 用户登录:用户输入凭证(如用户名和密码)并发送给服务器。
  2. 服务器验证:服务器验证凭证的有效性。
  3. 生成JWT:如果凭证有效,服务器生成JWT,并将其返回给客户端。
  4. 客户端存储:客户端存储JWT(通常存储在localStorage或sessionStorage中)。
  5. 后续请求:客户端在后续请求中将JWT放在HTTP头中(通常是Authorization: Bearer <token>)。
  6. 服务器验证JWT:服务器接收请求,验证JWT的有效性,并根据JWT中的信息执行相应的操作。
  • 过期时间:JWT通常会设置过期时间(exp),确保令牌在一定时间后失效。
  • 密钥管理:确保密钥的安全性,避免泄露。
  • HTTPS:始终使用HTTPS来传输JWT,以防止中间人攻击。

JWT 登录验证实现详细步骤

1. 添加依赖

首先,你需要在你的项目中添加JWT的相关依赖。以Maven为例,打开pom.xml并添加以下依赖:

<dependency>
    <groupId>io.jsonwebtoken</groupId>
    <artifactId>jjwt</artifactId>
    <version>0.9.1</version>
</dependency>

2. 创建JWT工具类

创建一个工具类来处理JWT的生成和验证。

JwtUtil.java

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.JwtBuilder;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;

public class JwtUtil {
    private static final String SECRET_KEY = "your_secret_key"; // 替换为你的密钥
    private static final long EXPIRATION_TIME = 86400000; // 24小时

    // 生成JWT
    public static String generateToken(String username) {
        Map<String, Object> claims = new HashMap<>();
        claims.put("username", username);

        JwtBuilder builder = Jwts.builder()
                .setClaims(claims)
                .setSubject(username)
                .setIssuedAt(new Date())
                .setExpiration(new Date(System.currentTimeMillis() + EXPIRATION_TIME))
                .signWith(SignatureAlgorithm.HS512, SECRET_KEY);
        
        return builder.compact();
    }

    // 验证JWT
    public static Claims validateToken(String token) {
        return Jwts.parser()
                .setSigningKey(SECRET_KEY)
                .parseClaimsJws(token)
                .getBody();
    }
}

3. 实现用户登录

在Controller层实现用户登录逻辑,验证用户身份并生成JWT。

AuthController.java

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping("/api/auth")
public class AuthController {

    @Autowired
    private UserService userService;

    @PostMapping("/login")
    public ResponseEntity<String> login(@RequestBody LoginRequest loginRequest) {
        // 验证用户身份
        User user = userService.authenticate(loginRequest.getUsername(), loginRequest.getPassword());
        if (user != null) {
            // 生成JWT
            String token = JwtUtil.generateToken(user.getUsername());
            return ResponseEntity.ok(token);
        } else {
            return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body("Invalid credentials");
        }
    }
}

4. 添加JWT过滤器

创建一个过滤器,用于拦截请求并验证JWT。

JwtRequestFilter.java

import io.jsonwebtoken.Claims;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@Component
public class JwtRequestFilter extends OncePerRequestFilter {

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
            throws ServletException, IOException {
        final String authorizationHeader = request.getHeader("Authorization");

        String username = null;
        String jwt = null;

        // 从请求头中获取JWT
        if (authorizationHeader != null && authorizationHeader.startsWith("Bearer ")) {
            jwt = authorizationHeader.substring(7);
            Claims claims = JwtUtil.validateToken(jwt);
            username = claims.getSubject();
        }

        // 设置用户信息到SecurityContext(如果需要的话)
        if (username != null) {
            // 可以在这里设置用户的权限等信息
        }

        chain.doFilter(request, response);
    }
}

5. 配置Spring Security

在Spring Security配置中添加JWT过滤器以保护需要身份验证的路由。

SecurityConfig.java

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private JwtRequestFilter jwtRequestFilter;

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.csrf().disable() // 禁用CSRF保护
            .authorizeRequests()
            .antMatchers("/api/auth/login").permitAll() // 允许登录请求
            .anyRequest().authenticated(); // 其他请求需要身份验证

        // 添加JWT过滤器
        http.addFilterBefore(jwtRequestFilter, UsernamePasswordAuthenticationFilter.class);
    }
}

6. 用户服务实现

实现用户验证逻辑的服务类。

UserService.java

import org.springframework.stereotype.Service;

@Service
public class UserService {

    public User authenticate(String username, String password) {
        // 这里可以调用数据库查询用户并验证密码
        // 这是一个简单示例,实际应用中应加密密码并进行安全检查
        if ("user".equals(username) && "password".equals(password)) {
            return new User(username); // 返回用户对象
        }
        return null; // 身份验证失败
    }
}

7. 用户类和请求类

定义用户类和登录请求类。

User.java

public class User {
    private String username;

    public User(String username) {
        this.username = username;
    }

    public String getUsername() {
        return username;
    }
}

LoginRequest.java

public class LoginRequest {
    private String username;
    private String password;

    // Getter和Setter
    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }
}

总结

以上是使用JWT实现登录验证的完整步骤。主要步骤包括:

  1. 添加依赖:引入JWT库。
  2. 创建JWT工具类:生成和验证JWT。
  3. 实现用户登录:在Controller中处理登录请求,生成JWT。
  4. 添加JWT过滤器:拦截请求并验证JWT。
  5. 配置Spring Security:保护需要身份验证的路由。
  6. 实现用户服务:验证用户身份。
  7. 定义用户类和请求类:用于处理用户信息和登录请求。