千家信息网

JWT怎么用

发表于:2026-11-01 作者:千家信息网编辑
千家信息网最后更新 2026年11月01日,这期内容当中小编将会给大家带来有关JWT怎么用,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。1. 定义JWT简称JSON Web Token,通过JSON形式作为W
千家信息网最后更新 2026年11月01日JWT怎么用

这期内容当中小编将会给大家带来有关JWT怎么用,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。

1. 定义

JWT简称JSON Web Token,通过JSON形式作为Web应用中的令牌,将信息作为JSON对象在各方之间安全传输,在数据传输过程中还可以完成数据加密、签名等相关处理。

2. 作用

2.1 授权

JWT的最常见方案,一旦用户登录,每个后续请求将包括JWT,从而允许访问系统的资源,一般适用于单点登录系统,因为开销很小并且可以在不同的域中轻松使用。

2.2 信息交换

  • JWT是在各方之间安全地传输信息的好方法,因为可以对JWT进行签名,例如使用公钥或者私钥对,由于签名是使用标头和有效负载计算的,还可以验证内容是否遭到篡改。

  • JWT跟Session不一样,JWT存储在客户端,Session存储在服务器端,服务器断电后Session就会被销毁,而JWT因为存储在客户端,所以就不会被影响,只要JWT不过期,就可以继续使用。

3. 优势

3.1 基于Session认证

  • Session都是保存在内存中,而随着认证用户的增多,服务端的开销会明显增大。

  • 用户认证之后,服务端做认证记录,如果认证的记录被保存在内存中的话,这意味着用户下次请求还必须要请求在这台服务器上,这样才能拿到授权的资源,在分布式系统中,限制了负载均衡器的能力,也限制了应用的扩展能力。

  • CSRF跨站伪造请求攻击攻击,Session是基于Cookie进行用户识别的,如果Cookie被截获,用户会很容易受到跨站请求伪造的攻击。

  • Sessionid就是一个特征值,表达的信息不够丰富,不容易扩展,而且如果后端应用是多节点部署,需要实现session共享机制,不方便集群应用。

3.2 基于JWT认证

3.2.1 认证流程
  • 前端通过Web表单将自己的用户名和密码发送到后端的接口,一般是为http post请求,尽量通过SSL加密的传输,避免泄漏敏感信息。

  • 后端核对用户名和密码成功后,将用户的id等其他信息作为JWT负载,将其与头部分别进行Base64编码拼接后签名,形成的JWT就是一个形同lll.zzz.xxx的字符串,格式为head.payload.signature。

  • 后端将JWT字符串作为登录成功的返回结果返回给前端,前端可以将返回的结果保存在localStorage或sessionStorage上,退出登录时前端删除保存的JWT。

  • 前端为了解决XSS和XSRF问题,在每次请求时将JWT放入http head中的authorization位置。

  • 后端检查是否存在,如存在验证JWT的有效性,检查签名是否正确,检查Token是否过期,检查Token的接收方是否是自己。

  • 验证通过后,后端使用JWT中包含的用户信息进行其他逻辑操作,返回相应结果。

3.2.2 特点
  • 简洁,可以通过Url和Http参数或者在Http请求头发送,因为数据量小,传输速度也很快。

  • 自包含,负载中包含了所有用户所需要的信息,避免了多次查询数据库。

  • Token是以JSON加密的形式保存在客户端的,所以JWT是跨语言的,原则上任何Web形式都支持。

  • 不需要在服务端保存会话信息,特别适用于分布式微服务。

4. jwt结构

token string ====> header.payload.singnature token

4.1 令牌组成

  • 标头(Header)

  • 有效载荷(Payload)

  • 签名(Signature)

  • 因此,JWT通常如下所示:xxxxx.yyyyy.zzzzz Header.Payload.Signature

4.2 Header

  • 标头通常由两部分组成:令牌的类型和所使用的签名算法,例如HMAC SHA256或RSA,它会使用 Base64 编码组成 JWT 结构的第一部分。

  • Base64是一种编码,是可以被翻译回原来的样子,它并不是一种加密过程。

{  "alg": "HS256",  "typ": "JWT"}

4.3 Payload

令牌的第二部分是有效负载,其中包含声明。声明是有关实体和其他数据的声明,也使用 Base64 编码组成 JWT 结构的第二部分。

{  "sub": "1234567890",  "name": "John Doe",  "admin": true}

4.4 Signature

  • 前面两部分都是使用 Base64 进行编码的,即前端可以获得里面的信息。Signature 需要使用编码后的 header 和 payload 以及我们提供的一个密钥,然后使用 header 中指定的签名算法(HS256)进行签名。

  • 签名的作用是保证 JWT 没有被篡改过,例如HMACSHA256(base64UrlEncode(header) + "." + base64UrlEncode(payload),secret)。

  • 如果对头部以及负载的内容解码之后进行修改,再进行编码,最后加上之前的签名组合形成新的JWT的话,那么服务器端会判断出新的头部和负载形成的签名和JWT附带上的签名是不一样的,如果要对新的头部和负载进行签名,在不知道服务器加密时用的密钥的话,得出来的签名也是不一样的。

  • 在JWT中,不应该在负载里面加入任何敏感的数据。

4.5 最后结果

5. SpringBoot整合jwt

pom.xml

    4.0.0            org.springframework.boot        spring-boot-starter-parent        2.3.3.RELEASE                 org.example    springboot-jwt-token    1.0-SNAPSHOT            1.8                            org.springframework.boot            spring-boot-starter-web                                    com.auth0            java-jwt            3.10.3                            org.projectlombok            lombok            true                                    org.mybatis.spring.boot            mybatis-spring-boot-starter            2.1.3                                    mysql            mysql-connector-java            8.0.18                                    com.alibaba            druid            1.1.23                                                    org.springframework.boot                spring-boot-maven-plugin                        

application.properties

spring.application.name=jwtspring.datasource.type=com.alibaba.druid.pool.DruidDataSourcespring.datasource.driver-class-name=com.mysql.cj.jdbc.Driverspring.datasource.url=jdbc:mysql://localhost:3306/db1?useUnicode=true&characterEncoding=utf8&useSSL=true&serverTimezone=UTC&useSSL=falsespring.datasource.username=rootmybatis.type-aliases-package=com.alfred.beanmybatis.mapper-locations=classpath:com/alfred/mapper/*.xmllogging.level.com.alfred.dao=debug

mybatis xml映射文件

    

实体类

@Data@Accessors(chain = true)public class User {    private String id;    private String name;    private String password;}

dao 层

@Mapperpublic interface UserDao {    /**     * 登录     *     * @param user User对象     * @return User对象     */    User login(User user);}

service层

public interface UserService {    /**     * 登录接口     *     * @param user 表单中的user     * @return 数据库中查询到的User     */    User login(User user);}
@Servicepublic class UserServiceImpl implements UserService {    @Resource    private UserDao userDAO;    @Transactional(propagation = Propagation.SUPPORTS)    @Override    public User login(User user) {        User userDb = userDAO.login(user);        if (userDb != null) {            return userDb;        }        throw new RuntimeException("认证失败");    }}

jwt工具类

public class JwtUtil {    private static String SECRET = "hell world";    /**     * 生成token     *     * @param map map集合     * @return token     */    public static String getToken(Map map) {        JWTCreator.Builder builder = JWT.create();        map.forEach(builder::withClaim);        Calendar calendar = Calendar.getInstance();        calendar.add(Calendar.HOUR, 12);        return builder.sign(Algorithm.HMAC256(SECRET));    }    /**     * 验证token     *     * @param token token字符串     * @return 验证接口     */    public static DecodedJWT verify(String token) {        return JWT.require(Algorithm.HMAC256(SECRET)).build().verify(token);    }}

拦截器

@Slf4jpublic class JwtInterceptor implements HandlerInterceptor {    @Override    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {        // 获取请求头中的令牌        String token = request.getHeader("token");        log.info("当前token为:{}", token);        Map map = new HashMap<>();        try {            JwtUtil.verify(token);            return true;        } catch (SignatureVerificationException e) {            e.printStackTrace();            map.put("msg", "签名不一致");        } catch (TokenExpiredException e) {            e.printStackTrace();            map.put("msg", "令牌过期");        } catch (AlgorithmMismatchException e) {            e.printStackTrace();            map.put("msg", "算法不匹配");        } catch (InvalidClaimException e) {            e.printStackTrace();            map.put("msg", "失效的payload");        } catch (Exception e) {            e.printStackTrace();            map.put("msg", "token无效");        }        map.put("state", false);        //响应到前台: 将map转为json        String json = new ObjectMapper().writeValueAsString(map);        response.setContentType("application/json;charset=UTF-8");        response.getWriter().println(json);        return false;    }}
@Configurationpublic class InterceptorConfig implements WebMvcConfigurer {    @Override    public void addInterceptors(InterceptorRegistry registry) {        registry.addInterceptor(new JwtInterceptor())                .addPathPatterns("/user/test")                .excludePathPatterns("/user/login");    }}

controller层

@RestController@Slf4jpublic class UserController {    @Resource    private UserService userService;    @GetMapping("/user/login")    public Map login(User user) {        log.info("用户名:{}", user.getName());        log.info("密码: {}", user.getPassword());        Map map = new HashMap<>();        try {            User userDb = userService.login(user);            Map payload = new HashMap<>();            payload.put("id", userDb.getId());            payload.put("name", userDb.getName());            String token = JwtUtil.getToken(payload);            map.put("state", true);            map.put("msg", "登录成功");            map.put("token", token);            return map;        } catch (Exception e) {            e.printStackTrace();            map.put("state", false);            map.put("msg", e.getMessage());            map.put("token", "");        }        return map;    }    @PostMapping("/user/test")    public Map test(HttpServletRequest request) {        String token = request.getHeader("token");        DecodedJWT verify = JwtUtil.verify(token);        String id = verify.getClaim("id").asString();        String name = verify.getClaim("name").asString();        log.info("id:{}", id);        log.info("用户名: {}", name);        // TODO 业务逻辑        Map map = new HashMap<>();        map.put("state", true);        map.put("msg", "请求成功");        return map;    }}

上述就是小编为大家分享的JWT怎么用了,如果刚好有类似的疑惑,不妨参照上述分析进行理解。如果想知道更多相关知识,欢迎关注行业资讯频道。

用户 信息 服务 认证 数据 编码 登录 令牌 前端 服务器 传输 加密 验证 有效 成功 内容 头部 用户名 结果 应用 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 蓝思科技飞鸽互联网 互联网与科技发展 北京互联网科技公司 互联网科技论坛 玖二柒互联网科技公司待遇 深圳前海聚择互联网科技有限公司 中国互联网有什么科技含量 成都互联网科技公司100强 佳云科技和互联网广告 彤创互联网科技有限公司 互联网与医疗科技 成都互联网科技公司工作好不好 天津腾达互联网科技有限公司 燊美集互联网科技有限公司 广州新华互联网科技学校电竞方面 企晟互联网信息科技有限公司 保险科技服务互联网营销体系 合肥互联网科技公司公章图片 东营紫格互联网科技 抖集互联网科技技术咨询 金融科技还是互联网 北京互联网科技有限公司 互联网科技论文 互联网科技生活的内容 海南科技产业互联网平台 工业互联网等科技实现智能化赋能 互联网科技公司营业执照怎么办理 伊宁互联网科技做什么的 本届互联网大会上的黑科技 容联科技互联网电商
0