比较SpringBoot和Node.js之间的JWT授权

虽然两者都有其复杂性,但SpringBoot的学习曲线肯定更陡峭!

Spring Boot 和 Node.js 都是流行的后端开发框架,它们都可以用于实现 JWT(JSON Web Token)授权机制。下面是对比它们之间的 JWT 授权的一些方面:

  1. 语言和生态系统:
    • Spring Boot 使用 Java 语言,而 Node.js 使用 JavaScript。
    • Spring Boot 生态系统提供了广泛的库和工具,但可能更加臃肿,因为 Java 本身就是一种较为重量级的语言。Node.js 生态系统则更加轻量级和灵活,因为 JavaScript 在前端和后端都有应用,所以它的社区更大、更活跃。
  • JWT库:
    • Spring Boot 中的 JWT 授权通常使用 Spring Security JWT 模块。这个模块提供了JWT的生成、验证等功能,并且可以与Spring Security整合,实现强大的安全功能。
    • 在 Node.js 中,有很多可用的 JWT 库,比如 jsonwebtoken、express-jwt 等,它们提供了类似的功能,让你可以很方便地生成和验证 JWT。
  • 易用性:
    • 在Spring Boot中,配置和集成Spring Security JWT可能需要一些额外的工作,特别是对于新手来说可能有一定的学习曲线。
    • 在 Node.js 中,由于 JavaScript 的灵活性,通常可以更快速地启动一个简单的 JWT 授权系统,因为可以直接使用现有的库和中间件来实现。
  • 性能:
    • 一般来说,Spring Boot 在性能方面可能稍微落后于 Node.js,因为Java应用程序通常需要更多的资源来运行。但在实际情况中,性能取决于具体的应用场景、硬件配置以及优化水平。
  • 社区支持和文档:
    • Node.js 社区因为其活跃度和庞大的规模,提供了丰富的文档和示例,可以很容易地找到解决方案和教程。
    • Spring Boot 作为一个成熟的框架,也有很多官方文档和社区资源,但相对于Node.js来说,可能会稍显稀少。

    综上所述,选择使用 Spring Boot 还是 Node.js 实现 JWT 授权取决于你的项目需求、团队技术栈以及个人偏好。如果你已经在使用 Spring Boot 或者 Java,那么选择 Spring Security JWT 可能更为方便。如果你更熟悉 JavaScript 或者已经在使用 Node.js,那么使用 Node.js 实现 JWT 授权可能更为适合。

    在springBoot中实现jwt授权
    在Spring Boot应用中使用中实现JWT授权的步骤如下:

    添加依赖:
    引入`io.jsonwebtoken:io.jsonwebtoken:jjwt包,用于生成和解析JWT。

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

    创建JWT工具类:创建一个JWT工具类,用于生成和解析JWT。

    import io.jsonwebtoken.Claims;
    import io.jsonwebtoken.Jwts;
    import io.jsonwebtoken.SignatureAlgorithm;
    import io.jsonwebtoken.security.Keys;

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

    public class JwtUtil {

        private static final String SECRET_KEY = "your-secret-key";

        public static String createJWT(String subject, String issue, Object claim, long ttlMillis) {
            long nowMillis = System.currentTimeMillis();
            Date now = new Date(nowMillis);

            Date expireDate = new Date(nowMillis + ttlMillis);

            Map<String, Object> claims = new HashMap<>();
            claims.put(
    "user", claim);

            return Jwts.builder()
                    .setSubject(subject)
                    .setIssuer(issue)
                    .setId(issue)
                    .setClaims(claims)
                    .setIssuedAt(now)
                    .setExpiration(expireDate)
                    .signWith(getSignatureAlgorithm(), getSignedKey())
                    .compact();
        }

        private static Key getSignedKey() {
            byte[] apiKeySecretBytes = DatatypeConverter.parseBase64Binary(SECRET_KEY);
            return Keys.hmacShaKeyFor(apiKeySecretBytes);
        }

        private static SignatureAlgorithm getSignatureAlgorithm() {
            return SignatureAlgorithm.HS256;
        }

        public static Claims parseJWT(String jwt) {
            Claims claims;
            try {
                claims = Jwts.parser().setSigningKey(getSignedKey()).parseClaimsJws(jwt).getBody();
            } catch (Exception ex) {
                claims = null;
            }
            return claims;
        }

        public static String getClaims(String jwt, String claimName) {
            Claims claims = parseJWT(jwt);
            if (claims != null) {
                return claims.get(claimName, String.class);
            }
            return null;
        }
    }

    配置Spring Security:在application.properties
    ​​​​文件中配置Spring Security,以及JWT的相关配置。

    spring.security.oauth2.resourceserver.jwt.jwt-configuration=com.example.security.JwtConfig
    spring.security.oauth2.resourceserver.jwt.issuer-uri=http://your-issuer-uri
    spring.security.oauth2.resourceserver.jwt.key-uri=http:
    //your-key-uri


    创建JWT配置类:创建一个JWT配置类,用于配置Spring Security。

    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.security.config.annotation.web.builders.WebSecurity;
    import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
    import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
    import org.springframework.security.config.http.SessionCreationPolicy;
    import org.springframework.security.config.web.server.ServerHttpSecurity;
    import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

    import io.jsonwebtoken.security.Keys;

    import java.security.Key;

    @Configuration
    @EnableWebSecurity
    public class JwtConfig extends WebSecurityConfigurerAdapter {

        private final JwtFilter jwtFilter;

        public JwtConfig(JwtFilter jwtFilter) {
            this.jwtFilter = jwtFilter;
        }

        @Bean
        public Key key() {
            byte[] apiKeySecretBytes = DatatypeConverter.parseBase64Binary("your-secret-key");
            return Keys.hmacShaKeyFor(apiKeySecretBytes);
        }

        @Override
        protected void configure(ServerHttpSecurity http) throws Exception {
            http
                    .csrf().disable()
                    .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                    .and()
                    .authorizeExchange()
                    .anyExchange().authenticated()
                    .and()
                    .addFilterBefore(jwtFilter, UsernamePasswordAuthenticationFilter.class);
        }
    }


    创建JWT过滤器:创建一个JWT过滤器,用于验证JWT。

    在node.js中实现jwt授权
    要在Node.js中生成JWT token,可以使用jsonwebtoken库。首先需要安装jsonwebtoken依赖,然后在代码中引入jsonwebtoken库,使用sign方法生成token。

    安装依赖:jsonwebtoken

    npm install jsonwebtoken

    创建文件,并在其中定义和方法:jwt.jssignverify

    const jwt = require('jsonwebtoken');
    const key = 'your-secret-key'; // 生成token的密钥

    // 创建方法sign用于产生token
    function sign(load) {
      let payload = { data: load };
      let expiresIn = { expiresIn: 86400 };
    // 1天
      return jwt.sign(payload, key, expiresIn);
    }

    // 创建方法verify用于验证token
    function verify(token) {
      try {
        jwt.verify(token, key);
        return true;
      } catch (error) {
        return false;
      }
    }

    // 导出verify和sign方法
    module.exports = { sign, verify };

    在您的应用程序中使用文件:jwt.js

    const jwt = require('jsonwebtoken');
    const JWT_SECRET = 'your-secret-key'; // 与jwt.js中的密钥相同

    // 生成token
    function generateToken(payload) {
      return jwt.sign(payload, JWT_SECRET, { expiresIn: '1h' });
    }

    // 验证token
    function verifyToken(token) {
      try {
        const decoded = jwt.verify(token, JWT_SECRET);
        return decoded;
      } catch (error) {
        console.error('JWT verification failed');
        return false;
      }
    }

    // 在Express.js中创建JWT验证中间件
    function authenticateToken(req, res, next) {
      const token = req.header('Authorization');
      if (!token) return res.status(401).send('Access denied');
      try {
        const decoded = verifyToken(token.replace('Bearer ', ''));
    // 去除'Bearer '前缀
        req.user = decoded;
        next();
      } catch (error) {
        res.status(403).send('Invalid token');
      }
    }

    // 在路由处理函数中使用JWT验证中间件
    app.get('/protected', authenticateToken, (req, res) => {
      res.json({ message: 'This is a protected route', user: req.user });
    });