怎么使用jwt,token以及redis进行续期?

怎么使用jwt,token以及redis进行续期?

  1. 什么是jwt?

  2. 什么是token?

  3. 结合 JWT、Token 和 Redis 进行续期的一般步骤:

    1. 生成 JWT: 用户登录成功后,服务器生成一个 JWT,并返回给客户端。

      import io.jsonwebtoken.Jwts;
      import io.jsonwebtoken.SignatureAlgorithm;
      
      public class JwtUtil {
          private static final String SECRET_KEY = "yourSecretKey";
      
          public static String generateToken(String subject) {
              return Jwts.builder()
                      .setSubject(subject)
                      .signWith(SignatureAlgorithm.HS256, SECRET_KEY)
                      .compact();
          }
      }
      
    2. 将 JWT 存储到 Redis: 服务器将生成的 JWT 存储到 Redis 中,以便后续验证和续期。

      import redis.clients.jedis.Jedis;
      
      public class RedisUtil {
          private static final String REDIS_HOST = "localhost";
          private static final int REDIS_PORT = 6379;
      
          public static void storeTokenInRedis(String key, String token) {
              try (Jedis jedis = new Jedis(REDIS_HOST, REDIS_PORT)) {
                  jedis.set(key, token);
              }
          }
      }
      
    3. 客户端保存 JWT: 客户端收到 JWT 后,将其保存在本地,通常可以存储在 Local Storage 或者 Session Storage 中。

      1. LocalStorage 或 SessionStorage: 在 Web 应用中,可以将 JWT 存储在浏览器的 LocalStorage 或 SessionStorage 中。这些存储方式都是客户端本地的存储机制,可以通过 JavaScript API 进行读写操作。LocalStorage 的数据会一直保存,除非用户手动清除,而 SessionStorage 的数据则只在当前会话期间有效。
      // 将 JWT 存储到 LocalStorage
      localStorage.setItem('jwtToken', token);
      
      // 从 LocalStorage 获取 JWT
      const token = localStorage.getItem('jwtToken');
      
      1. Cookie: 另一种常见的方式是将 JWT 存储在 Cookie 中。通过设置 Cookie 的方式,可以在客户端和服务器之间进行自动传递,而不需要显式地在请求头中添加 JWT。
      // 将 JWT 存储到 Cookie
      document.cookie = `jwtToken=${token}; path=/;`;
      
      // 从 Cookie 获取 JWT
      const token = document.cookie.split('; ').find(row => row.startsWith('jwtToken')).split('=')[1];
      
      1. 内存: 在某些情况下,可以将 JWT 存储在客户端的内存中。这种方式通常用于移动应用或桌面应用等场景,不适用于 Web 应用,因为 Web 页面刷新或关闭后,内存中的数据会丢失。
      // 在 Java 中使用内存保存 JWT 的示例
      String jwtToken;
      
    4. 使用 JWT 进行身份验证: 客户端在每次请求需要身份验证的资源时,将 JWT 放置在请求头中发送给服务器。

      import io.jsonwebtoken.Claims;
      import io.jsonwebtoken.Jws;
      import io.jsonwebtoken.Jwts;
      
      public class JwtUtil {
          private static final String SECRET_KEY = "yourSecretKey";
      
          public static boolean verifyToken(String token) {
              try {
                  Jws<Claims> claims = Jwts.parser().setSigningKey(SECRET_KEY).parseClaimsJws(token);
                  return true;
              } catch (Exception e) {
                  return false;
              }
          }
      }
      
    5. 验证 JWT 的有效性: 服务器收到请求后,验证 JWT 的签名和有效期等信息,以确认其有效性。

      1. 解析 JWT: 首先,需要解析 JWT,并验证其格式是否正确。JWT 通常由三部分组成:Header、Payload 和 Signature。可以使用相应的库或工具来解析 JWT,确保它们符合 JWT 的标准格式。
      2. 验证签名: JWT 的 Signature 部分由 Header 和 Payload 使用指定的算法签名而成。为了验证 JWT 的真实性,需要使用相同的密钥和算法对 Header 和 Payload 进行签名,并与 JWT 中的 Signature 进行比较。如果两者匹配,则说明 JWT 没有被篡改过。
      3. 检查过期时间: JWT 中通常会包含一个过期时间(exp)字段,表示 JWT 的有效期。需要检查当前时间是否晚于过期时间,以确保 JWT 尚未过期。
      4. 可选:验证其他声明: JWT 中可能包含其他自定义声明,如用户角色、权限等。根据应用需求,可以对这些声明进行验证,以确保 JWT 的合法性。

      下面是一个使用 Java 的示例代码,演示如何验证 JWT 的有效性:

      import io.jsonwebtoken.Claims;
      import io.jsonwebtoken.Jwts;
      import io.jsonwebtoken.security.Keys;
      import java.security.Key;
      import java.util.Date;
      
      public class JwtUtil {
          private static final String SECRET_KEY = "yourSecretKey";
      
          public static boolean validateJwt(String token) {
              try {
                  Claims claims = Jwts.parserBuilder()
                          .setSigningKey(Keys.hmacShaKeyFor(SECRET_KEY.getBytes()))
                          .build()
                          .parseClaimsJws(token)
                          .getBody();
      
                  // 验证过期时间
                  Date expiration = claims.getExpiration();
                  if (expiration != null && expiration.before(new Date())) {
                      return false; // JWT 已过期
                  }
      
                  // 可选:其他声明的验证
                  // String username = claims.getSubject();
                  // List<String> roles = (List<String>) claims.get("roles");
                  // 进行额外的声明验证
      
                  return true; // JWT 验证通过
              } catch (Exception e) {
                  return false; // JWT 验证失败
              }
          }
      }
      

      在上述代码中,validateJwt 方法接受一个 JWT,并返回一个布尔值,指示该 JWT 是否有效。如果 JWT 有效,则返回 true,否则返回 false

    6. 检查 JWT 的过期时间: 如果 JWT 即将过期,服务器可以发出一个新的 JWT,并更新 Redis 中的对应信息。

      • 在第五步中已完成
    7. 续期 JWT: 服务器根据业务逻辑和安全策略决定是否续期 JWT。如果续期,则生成一个新的 JWT,更新 Redis 中的相关信息,并将新的 JWT 返回给客户端。

      public class JwtUtil {
          private static final String SECRET_KEY = "yourSecretKey";
          private static final long EXPIRATION_TIME = 86400000L; // 24小时
      
          public static String refreshToken(String subject) {
              return Jwts.builder()
                      .setSubject(subject)
                      .setExpiration(new Date(System.currentTimeMillis() + EXPIRATION_TIME))
                      .signWith(SignatureAlgorithm.HS256, SECRET_KEY)
                      .compact();
          }
      }
      
    8. 客户端更新 JWT: 客户端收到新的 JWT 后,将其替换掉旧的 JWT,并更新本地存储中的 Token。

      import java.io.BufferedReader;
      import java.io.IOException;
      import java.io.InputStreamReader;
      import java.net.HttpURLConnection;
      import java.net.URL;
      
      public class UpdateJWTClient {
      
          private static String jwtToken = ""; // 存储 JWT 的变量,初始为空
      
          public static void main(String[] args) {
              // 模拟从服务器获取新的 JWT
              String newJWT = fetchNewJWT();
              
              if (newJWT != null && !newJWT.isEmpty()) {
                  // 替换旧的 JWT 并更新本地存储中的 Token
                  updateJWT(newJWT);
                  // 使用新的 JWT 发送请求
                  sendRequestWithNewJWT();
              } else {
                  System.out.println("Failed to fetch new JWT.");
              }
          }
      
          // 模拟从服务器获取新的 JWT
          private static String fetchNewJWT() {
              // 这里应该发送 HTTP 请求到服务器获取新的 JWT
              // 这里简化为直接返回一个模拟的 JWT
              return "new.jwt.token.example";
          }
      
          // 替换旧的 JWT 并更新本地存储中的 Token
          private static void updateJWT(String newToken) {
              jwtToken = newToken; // 替换旧的 JWT
              // 这里应该将新的 JWT 存储在本地,例如使用 SharedPreferences
              // 这里简化为打印出来
              System.out.println("Updated JWT: " + jwtToken);
          }
      
          // 使用新的 JWT 发送请求
          private static void sendRequestWithNewJWT() {
              try {
                  URL url = new URL("https://example.com/api/resource");
                  HttpURLConnection connection = (HttpURLConnection) url.openConnection();
                  connection.setRequestMethod("GET");
                  connection.setRequestProperty("Authorization", "Bearer " + jwtToken);
      
                  int responseCode = connection.getResponseCode();
                  if (responseCode == HttpURLConnection.HTTP_OK) {
                      // 请求成功,读取响应
                      BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
                      String inputLine;
                      StringBuffer response = new StringBuffer();
                      while ((inputLine = reader.readLine()) != null) {
                          response.append(inputLine);
                      }
                      reader.close();
                      System.out.println("Response: " + response.toString());
                  } else {
                      // 请求失败
                      System.out.println("Failed to send request. Response code: " + responseCode);
                  }
              } catch (IOException e) {
                  e.printStackTrace();
              }
          }
      }
      

      在这个示例中,fetchNewJWT 方法模拟了从服务器获取新的 JWT,实际情况下应该发送 HTTP 请求到服务器获取。然后,updateJWT 方法用新的 JWT 替换旧的 JWT,并更新本地存储中的 Token。最后,sendRequestWithNewJWT 方法使用新的 JWT 发送请求到服务器。

  • 5
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
使用 `rest_framework_jwt` 进行 token 续期需要执行以下步骤: 1. 在 `settings.py` 中添加 `JWT_ALLOW_REFRESH` 配置项: ```python JWT_AUTH = { # ... 其他配置项 ... 'JWT_ALLOW_REFRESH': True, 'JWT_REFRESH_EXPIRATION_DELTA': datetime.timedelta(days=7), } ``` 其中,`JWT_ALLOW_REFRESH` 配置项表示是否允许使用 refresh token 进行 token 续期,`JWT_REFRESH_EXPIRATION_DELTA` 配置项表示 refresh token 的有效期,这里设置为 7 天。 2. 在 `urls.py` 中添加 `refresh_jwt_token` 视图的路由: ```python from rest_framework_jwt.views import refresh_jwt_token urlpatterns = [ # ... 其他路由 ... path('api/token/refresh/', refresh_jwt_token), ] ``` 3. 在前端代码中,当 token 过期后,使用 refresh token 进行 token 续期。示例代码如下: ```javascript const refreshToken = localStorage.getItem('refreshToken'); if (refreshToken) { fetch('/api/token/refresh/', { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ refresh: refreshToken }), }) .then((response) => response.json()) .then((data) => { localStorage.setItem('accessToken', data.access); localStorage.setItem('refreshToken', data.refresh); }) .catch((error) => { console.error('Failed to refresh token', error); }); } else { console.error('No refresh token found'); } ``` 在上面的代码中,我们首先从本地存储中获取 refresh token,然后使用 `fetch` 发送 POST 请求到 `/api/token/refresh/` 视图,将 refresh token 作为请求体的 `refresh` 参数。在成功获取到新的 access token 和 refresh token 后,我们将它们保存到本地存储中。 希望这可以帮助你理解如何使用 `rest_framework_jwt` 进行 token 续期

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值