首页 > 其他分享 >Json Web Token

Json Web Token

时间:2023-08-02 13:11:19浏览次数:32  
标签:Web 令牌 map JWT Token Json token 服务器

什么是Json Web Token

JWT代表JSON Web Token,是一种用于在网络应用中传递信息的安全、紧凑的标准。它主要用于身份验证和授权,并且被广泛用于前后端分离的应用和单点登录系统。

JWT由三部分组成,通过点号(.)分隔,分别是:

  1. Header(头部):包含了两部分信息,令牌的类型(通常是"JWT")和所使用的加密算法,例如HMAC SHA256或RSA。
  2. Payload(负载):也称为Claims(声明),包含了一些实际需要传递的数据。这部分数据可以是预定义的标准声明(例如用户ID、过期时间等),也可以是自定义的声明。
  3. Signature(签名):使用指定的算法对Header和Payload进行签名,以确保令牌的完整性和真实性。签名需要使用一个秘钥,这样服务器可以使用秘钥来验证签名,从而确认该令牌的合法性。

在用户进行登录认证成功后,服务器会生成一个JWT并返回给客户端。客户端在后续的请求中携带这个JWT作为认证凭证,服务端通过验证JWT的签名来确定用户的身份和权限。由于JWT是自包含的,服务端不需要在数据库中查询用户信息,从而减轻了服务器的负担,并且提高了性能和可扩展性。

需要注意的是,由于JWT是基于Base64编码的,所以虽然它是安全的,但是不应该在JWT中存储敏感信息,因为Base64编码可以被解码。如果需要在JWT中传递敏感信息,应该对其进行加密处理。

Json web Token的应用场景

  • Authorization (授权) : 这是使用JWT的最常见场景。一旦用户登录,后续每个请求都将包含JWT,允许用户访问该令牌允许的路由、服务和资源。单点登录是现在广泛使用的JWT的一个特性,因为它的开销很小,并且可以轻松地跨域使用。
  • Information Exchange (信息交换) : 对于安全的在各方之间传输信息而言,JSON Web Tokens无疑是一种很好的方式。因为JWT可以被签名,例如,用公钥/私钥对,你可以确定发送人就是它们所说的那个人。另外,由于签名是使用头和有效负载计算的,您还可以验证内容没有被篡改。

基于Token的身份认证 与 基于服务器的身份认证

  1. 基于服务器的身份认证

    • 传统的做法是将已经认证过的用户信息存储在服务器上,比如Session。用户下次请求的时候带着Session ID,然后服务器以此检查用户是否认证过。
    • Sessions : 每次用户认证通过以后,服务器需要创建一条记录保存用户信息,通常是在内存中,随着认证通过的用户越来越多,服务器的在这里的开销就会越来越大。
    • Scalability : 由于Session是在内存中的,这就带来一些扩展性的问题。
    • CORS : 当我们想要扩展我们的应用,让我们的数据被多个移动设备使用时,我们必须考虑跨资源共享问题。当使用AJAX调用从另一个域名下获取资源时,我们可能会遇到禁止请求的问题。
    • CSRF : 用户很容易受到CSRF攻击。
  2. JWT与Session的异同点

  • 它们都是存储用户信息,然而,Session是在服务器端的,而JWT是在客户端的。
  • Session方式存储用户信息的最大问题在于要占用大量服务器内存,增加服务器的开销。
  • JWT方式将用户状态分散到了客户端中,可以明显减轻服务端的内存压力。
  • Session的状态是存储在服务器端,客户端只有session id;而Token的状态是存储在客户端。

Json Web Token的认证流程

(https://images.cnblogs.com/cnblogs_com/-xyk/1824054/o_230801051515_Snipaste_2023-08-01_13-14-01.png)

Json Web Token的使用

  1. 引入依赖

    <dependency>
        <groupId>com.auth0</groupId>
        <artifactId>java-jwt</artifactId>
        <version>4.3.0</version>
    </dependency>
    
  2. JWT的简单使用

class Demo1ApplicationTests {
    private String tokenStr = "token-JWT";

    // 创建 JSON Web Token (JWT) 的方法,其中包含了用户名、用户ID和过期时间
    String createJWT() {
        Calendar calendar = Calendar.getInstance();
        // 将当前时间增加 150 秒(2 分钟30秒)
        calendar.add(Calendar.SECOND, 150); 
        return JWT.create()
                .withClaim("username", "jack") // 添加一个名为 "username" 的声明,值为 "jack"
                .withClaim("userid", 1) // 添加一个名为 "userid" 的声明,值为 1
                .withExpiresAt(calendar.getTime()) // 将令牌的过期时间设置为计算后的时间
                .sign(Algorithm.HMAC256(tokenStr)); // 使用 HMAC256 算法和给定的 tokenStr 对令牌进行签名
    }

    @Test
    void TestJWT() {
        System.out.println(createJWT()); // 为了测试目的,将生成的 JWT 打印到控制台
        // 使用相同的 tokenStr 验证 JWT 并获取解码后的令牌
        JWTVerifier verifier = JWT.require(Algorithm.HMAC256(tokenStr)).build();
        DecodedJWT verify = verifier.verify(createJWT());
        System.out.println(verify.getClaim("username").asString()); // 打印解码后的令牌中的 "username" 声明
        System.out.println(verify.getClaim("userid").asInt()); // 打印解码后的令牌中的 "userid" 声明
    }
}
  1. JWT工具类的封装

    public class JWTUtil {
        private static final String SIGN = "secretKey";
        public static String getToken(Map<String,String> map){
            Calendar calendar = Calendar.getInstance();
            calendar.set(Calendar.DATE,3);
            JWTCreator.Builder builder = JWT.create();
            map.forEach((k,v)->{
                builder.withClaim(k,v);
            });
            String token = builder.withExpiresAt(calendar.getTime()).sign(Algorithm.HMAC256(SIGN));
            return token;
        }
    
        public static DecodedJWT verify(String token){
            return JWT.require(Algorithm.HMAC256(SIGN)).build().verify(token);
        }
    }
    
  2. 创建拦截器

    public class JwtInterceptor implements HandlerInterceptor {
        @Override
        public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
            String token = request.getHeader("token");
            System.out.println(token);
            Map<String,Object> map = new HashMap<>();
            try {
                JWTUtil.verify(token);
                map.put("state",true);
                map.put("msg","认证成功");
                return true;
            }catch (SignatureVerificationException e){
                map.put("msg","无效签名");
                e.printStackTrace();
            }catch (TokenExpiredException e){
                map.put("msg","token过期");
                e.printStackTrace();
            }catch (AlgorithmMismatchException e){
                map.put("msg","算法不一致");
                e.printStackTrace();
            }catch (Exception e){
                map.put("msg","token无效");
                e.printStackTrace();
            }
            map.put("state",false);
            String json = new ObjectMapper().writeValueAsString(map);
            response.setContentType("application/json;charset=utf-8");
            response.getWriter().write(json);
            return false;
        }
    }
    
    
  3. 配置拦截器

    @Configuration
    public class InterceptorConfig implements WebMvcConfigurer {
        @Override
        public void addInterceptors(InterceptorRegistry registry) {
            registry.addInterceptor(new JwtInterceptor())
                    .addPathPatterns("/**")
                    .excludePathPatterns("/user");
        }
    }
    

标签:Web,令牌,map,JWT,Token,Json,token,服务器
From: https://www.cnblogs.com/-xyk/p/17600406.html

相关文章

  • 汉源高科工业级千兆2光8电工业环网交换机WEB管理型智能组环光纤收发器VLAN划分导轨式
    HY5700-7528G-X系列是汉源高科自主研发的全千兆二层网管工业以太网光纤交换机,支持8个10/100/1000Base-T自适应RJ45端口+2个100/1000Base-XSFP光口插槽。所有端口支持线速转发。HY5700-7528G-X具备L2网管功能,支持IPV4/IPV6管理,支持完备的安全防护机制、完善的ACL/QoS策略和丰富的VL......
  • System.Web.HttpException:“超过了最大请求长度。”
    BUG:前端想后端发送坐标数组,控制器出现了如下报错: Answer:该错误提示表明你的HTTP请求超过了服务器允许的最大请求长度。这是为了防止恶意攻击或意外的大型请求对服务器造成压力。为了解决这个问题,你可以尝试以下几种方法:增加服务器的最大请求长度:你可以在服务器的配置中......
  • WebService如何去掉后缀访问
    创建全局应用程序类Global.asax,在方法Application_BeginRequest并添加如下代码:利用替换的方式实现效果stringpath=Request.Url.ToString();path=Request.Url.LocalPath.ToString();if(path=="/IFS"){Contex......
  • vite 项目webstorm跳转失效 VSCode、vue 无法对 @ 路径 跳转 ,几乎适用于所有webpack、
    在根目录加一个jsconfig.json文件{"compilerOptions":{"baseUrl":".","paths":{"@/*":["src/*"]},"target":"ES6","allowSyntheticDefaultImports&q......
  • 让nlohmann json支持std::wstring和嵌套结构的序列化与反序列化
    nlohmannjson是一个star很高的C++json解析库。要让nlohmannjson支持某个类型T,只要给这个类型T实现一个偏特化的structadl_serializer<T>即可。adl_serializer是这个库里面针对泛型T预定义的适配器。而嵌套结构,本身就支持的。使用预定义的宏NLOHMANN_DEFINE_TYPE_NON_INTRUSI......
  • idea汉化教程 jetbrains系列工具DataGrip PyCharm WebStorm Intellij IDEA Goland cli
    这里以pycharm举例演示其他的ide类似操作。打开pycharmIDE如果是初次打开工具没有任何项目的情况下界面如下直接点击左侧plugins->输入chinese->选择Chinese(Simplified)点击Install。安装完成后重启IDE就已经是中文版了。有项目的情况界面如下点击File->settin......
  • PHPJSON数据格式常见应用及实例解析
    PHPJSON数据格式常见应用及实例解析随着Web应用的兴起和普及,数据的传输和处理已经成为Web开发中不可或缺的一部分。PHP作为一种广泛使用的服务器端编程语言,对于数据的处理和传输也有着非常丰富的支持。其中,JSON数据格式已经成为Web开发中最常用的数据格式之一。本文将结合实例,介......
  • 封装获取chrome和ie的webdriver
    importtimefromseleniumimportwebdriverfromselenium.webdriver.chrome.serviceimportServiceasChromeServicefromwebdriver_manager.chromeimportChromeDriverManagerfromselenium.webdriver.ie.serviceimportServiceasIEServicefromwebdriver_manag......
  • requests--post中json中文编码问题
    问题requestspost提交json数据时,默认在库中ensure_ascii为True。会对中文进行unicode编码。但是有的时候服务端并没有处理中文,没有进行解码,而我们又改不了服务端,就会出现问题!解决修改库的代码,添加上对应的ensure_ascii参数。不推荐,换个环境就用不了了。推荐:自己......
  • miniframe开源Web框架(适配Delphi、lazarus)
    miniframe开源Web框架,一个使用pascal脚本编写业务代码的服务端框架。框架已实现了HTTP服务、脚本解释执行、多种数据库连接、数据库缓冲池、连接缓冲池等底层支持。在此基础上使用者只需要关注自己的业务实现即可。源码及demo下载 编译及运行环境配置 github地址技术qun:821855479......