JWT-Erklärung und praktische Anwendung


1. Einleitung

        Dieser Blog basiert auf dem Blog eines großen Chefs. Der Zweck besteht darin, ihn von Hand zu tippen, damit ich mich besser daran erinnern kann. Gleichzeitig ist es auch nur für den Fall, dass der große Kerl den Blog löscht und ich gewonnen habe Ich werde in Zukunft keinen so guten Artikel mehr lesen können. Am Anfang ist mir die JWT-Technologie nicht aufgefallen. Bis zum Interview vor ein paar Tagen stellte der Interviewer diese Frage und ich war sofort verwirrt, also werde ich es dieses Mal nachholen. Originalartikel: JWT Detaillierte Erklärung

2. Was ist JWT?

        Bevor wir JWT einführen, schauen wir uns den Prozess der Verwendung von Token zur Benutzerauthentifizierung an:

  • Der Kunde verlangt eine Anmeldung mit Benutzername und Passwort.
  • Nach Erhalt der Anfrage überprüft der Server den Benutzernamen und das Passwort.
  • Nach erfolgreicher Überprüfung stellt der Server ein Token aus und gibt das Token dann an den Client zurück.
  • Nach Erhalt des Tokens kann der Client es speichern, beispielsweise in einem Cookie.
  • Der Client muss dieses Token jedes Mal mitführen, wenn er Interesse an den Server sendet, und es kann in einem Cookie oder Header übertragen werden.
  • Nach Erhalt der Anfrage überprüft der Server das in der Client-Anfrage enthaltene Token und gibt die Anforderungsdaten an den Client zurück, wenn die Überprüfung erfolgreich ist.

Im Vergleich zur herkömmlichen Sitzungsauthentifizierungsmethode spart diese tokenbasierte Authentifizierungsmethode Serverressourcen und ist für mobile Endgeräte und die Verteilung benutzerfreundlicher. Seine Vorteile sind wie folgt:

  • Unterstützen Sie den domänenübergreifenden Zugriff : Cookies können keine Domänen überqueren, und Token verwenden keine Cookies (vorausgesetzt, das Token ist im Header vorhanden), sodass nach dem Überqueren von Domänen kein Informationsverlust auftritt.
  • Zustandslos : Der Token-Mechanismus muss keine Sitzungsinformationen auf der Serverseite speichern, da das Token selbst die Informationen aller angemeldeten Benutzer enthält, sodass der Druck auf der Serverseite verringert werden kann.
  • Gilt eher für CDN : Alle Daten auf dem Server können über das Inhaltsverteilungsnetzwerk angefordert werden.
  • Besser geeignet für mobile Endgeräte : Wenn der Client eine Nicht-Browser-Plattform ist, werden Cookies nicht unterstützt, und die Verwendung der Token-Authentifizierung ist zu diesem Zeitpunkt viel einfacher.
  • Es besteht keine Notwendigkeit, CSRF zu berücksichtigen : Da Cookies nicht berücksichtigt werden, kommt CSRF in der Token-Authentifizierungsmethode nicht vor, sodass keine Notwendigkeit besteht, die CSRF-Verteidigung in Betracht zu ziehen.

Und JWT ist eine spezifische Implementierung des oben genannten Tokens. Der vollständige Name lautet JSON Web Token . Die offizielle Website-Adresse lautet: https://jwt.io/

Laienhaft ausgedrückt ist JWT im Wesentlichen eine Zeichenfolge, die Benutzerinformationen in einer JSON-Zeichenfolge speichert und dann ein JWT-Token codiert. Dieses JWT-Token verfügt über Signaturinformationen, die nach dem Empfang überprüft werden können. Es wurde manipuliert, also kann es sein Wird zur sicheren Übertragung von Informationen zwischen Parteien als JSON-Objekte verwendet. Der Verifizierungsprozess von JWT ist wie folgt:

  • Der Client sendet seinen Benutzernamen und sein Passwort in Form eines Formulars an die Backend-Schnittstelle. Bei diesem Vorgang handelt es sich im Allgemeinen um eine POST-Anfrage. Die empfohlene Methode ist die Verwendung einer SSL-verschlüsselten Übertragung, um eine Manipulation vertraulicher Informationen zu verhindern.
  • Nachdem das Backend den Benutzernamen und das Passwort überprüft hat, werden die Daten mit den Benutzerinformationen als JWT-Nutzlast verwendet, die im JWT-Header mit Base64 codiert und verkettet und dann signiert wird, um ein JWT-Token (z. B. eine Zeichenfolge von 111) zu bilden .aaa.nnn).
  • Das Backend gibt als Ergebnis einer erfolgreichen Anmeldung die JWT-Token-Zeichenfolge an den Client zurück. Der Client kann das zurückgegebene Ergebnis im Browser speichern und beim Abmelden das gespeicherte JWT-Token löschen.
  • Der Client fügt das JWT-Token bei jeder Anfrage in das Authorization-Attribut im HTTP-Anfrageheader ein.
  • Der Server überprüft das vom Client gesendete JWT-Token und die Gültigkeit des Prüfers, z. B. ob die Signatur korrekt ist, ob sie abgelaufen ist, ob der Empfänger des Tokens er selbst ist usw.
  • Nachdem die Überprüfung bestanden wurde, analysiert der Server die im JWT-Token enthaltenen Benutzerinformationen, führt andere logische Operationen aus und gibt das Ergebnis zurück.

3. Warum JWT verwenden?

        Bevor wir darüber sprechen, warum wir JWT verwenden, sprechen wir über die Nachteile von Session. Wir alle wissen, dass HTTP selbst ein zustandsloses Protokoll ist. Das heißt, wenn der Benutzer unserer Anwendung zur Benutzerauthentifizierung einen Benutzernamen und ein Kennwort bereitstellt, zeichnet das HTTP-Protokoll den authentifizierten Status nach der Authentifizierung nicht auf, und die nächste Anforderung wird nicht gesendet. Der Benutzer muss eine Authentifizierung durchführen, da wir gemäß dem HTTP-Protokoll nicht wissen, welcher Benutzer die Anfrage gesendet hat. Damit unsere Anwendung erkennen kann, welcher Benutzer die Anfrage gesendet hat, können wir uns erst nach dem Anmelden beim Server anmelden Der Benutzer ist zum ersten Mal erfolgreich. Speichern Sie die Anmeldeinformationen eines Benutzers. Diese Anmeldeinformationen werden in der Antwort an den Browser übergeben und ihm mitgeteilt, sie als Cookie zu speichern, damit sie bei der nächsten Anfrage an unseren Benutzer gesendet werden können gemacht, damit unsere Anwendung erkennen kann, von welchem ​​Benutzer die Anfrage kommt. Dies ist der traditionelle sitzungsbasierte Authentifizierungsprozess.
Fügen Sie hier eine Bildbeschreibung ein
Dann treten bei der herkömmlichen Sitzungsauthentifizierung die folgenden Probleme auf:

  • Die Anmeldeinformationen jedes Benutzers werden in der Sitzung des Servers gespeichert. Mit zunehmender Benutzerzahl steigt der Overhead des Servers erheblich.
  • Da die Sitzung im physischen Speicher des Servers vorhanden ist, schlägt diese Methode in einem verteilten System fehl. Obwohl die Sitzungszustimmung in Redis gespeichert werden kann, wird dies zweifellos die Komplexität des Systems erhöhen, und für Anwendungen, die kein Redis erfordern, wird die Einführung einer zusätzlichen Cache-Middleware vergeblich sein.
  • Da die Sitzung vom Cookie abhängig ist, gibt es häufig keine Cookies für Nicht-Browser-Clients oder mobile Endgeräte, sodass die Verwendungsweise der Sitzung ungültig ist.
  • Da die Sitzungsauthentifizierung im Wesentlichen auf Cookies basiert, sind Benutzer beim Abfangen von Cookies anfällig für Cross-Site-Request-Forgery-Angriffe. Und wenn der Browser Cookies deaktiviert, schlägt auch diese Methode fehl.
  • Noch unanwendbarer ist es in einem System, in dem Front-End und Back-End getrennt sind, die Back-End-Bereitstellung kompliziert ist, die vom Client gesendete Anfrage häufig mehrere Middleware durchläuft, um den Server zu erreichen, und die Cookie-Informationen darüber Die Sitzung wird mehrfach weitergeleitet.
  • Da sie auf Cookies basiert und Cookies nicht domänenübergreifend sein können, kann die Sitzungsauthentifizierung nicht domänenübergreifend sein.

Apropos Sitzungen: Ich erinnerte mich, dass mir der Interviewer während des Interviews eine Frage gestellt hatte: Wie kann ich die Sitzung finden, wenn Cookies deaktiviert sind?
        Antwort: Es gibt zwei gängige Lösungen. Das erste ist das URL-Rewriting, bei dem die Sitzungs-ID direkt nach dem URL-Pfad angehängt wird. Das erste ist das ausgeblendete Formularfeld, das dem Formular ein ausgeblendetes Feld hinzufügt, damit die Sitzungs-ID beim Absenden des Formulars an den Server übergeben werden kann. Zum Beispiel:

<form name="testform" action="/xxx"> 
     <input type="hidden" name="jsessionid" value="ByOK3vjFD75aPnrF7C2HmdnV6QZcEbzWoWiBYEnLerjQ99zWpBng!-145788764"/>
     <input type="text"> 
</form>

Vorteile von JWTs:

  • Prägnant: JWT-Token hat eine kleine Datenmenge und eine schnelle Übertragungsgeschwindigkeit.
  • Da das JWT-Token in JSON-verschlüsselter Form auf dem Client gespeichert wird, ist JWT sprachübergreifend und wird grundsätzlich von jedem Webformular unterstützt.
  • Der Server muss keine Sitzungsinformationen speichern, das heißt, er ist nicht von Cookies und Sitzungen abhängig, weist also nicht die Nachteile der herkömmlichen Sitzungsauthentifizierung auf und eignet sich besonders für verteilte Mikrodienste.
  • Single-Sign-On-freundlich. Wenn eine Sitzung zur Identitätsauthentifizierung verwendet wird, ist es schwierig, eine einmalige Anmeldung zu erreichen, da Cookies nicht domänenübergreifend sein können. Wenn das Token jedoch zur Überprüfung verwendet wird, kann das Token im Speicher eines beliebigen Speicherorts auf dem Client gespeichert werden, nicht unbedingt in einem Cookie, sodass diese Probleme ohne die Verwendung von Cookies nicht auftreten.
  • Anwendbar auf das mobile Endgerät: Wenn die Sitzung zur Authentifizierung verwendet wird, müssen Informationen auf dem Server gespeichert werden. Diese Methode basiert auf Cookies und ist daher nicht auf das mobile Endgerät anwendbar.

4. Die Struktur von JWT

        JWT besteht aus drei Teilen: Header (Header), Nutzlast (Nutzlast) und Signatur (Signatur). Während der Übertragung werden die drei Teile des JWT Base64-kodiert und dann mit . verkettet, um die endgültige übertragene Zeichenfolge zu bilden.
Fügen Sie hier eine Bildbeschreibung ein
4.1 Header:
        Der JWT-Header ist ein JSON-Objekt, das die JWT-Metadaten beschreibt. Das Alt-Attribut gibt den auf die Signatur anwendbaren Algorithmus an, und der Standardwert ist HMAC SHA256 (dh HS256); das Typ-Attribut gibt den Typ des Tokens und des JWT an Token wird einheitlich als JWT geschrieben. Wenden Sie abschließend den Base64-URL-Algorithmus an, um das obige JSON-Objekt in eine Zeichenfolge umzuwandeln und zu speichern.

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

4.2 Nutzlast
        Der Nutzlastteil ist der Betreffteil des JWT und außerdem ein JSON-Objekt, das die zu übergebenden Daten enthält. JWT gibt Standardfelder zur Auswahl an.

iss:发行人
exp:到期时间
sub:主题
aud:用户
nbf:在此之前不可用
iat:发布时间
jti:JWT ID用于标识该JWT

Zusätzlich zu den oben genannten Standardfeldern können wir auch private Felder anpassen. Im Allgemeinen werden die Benutzerinformationsdaten wie folgt in die Nutzlast eingefügt

{
    
    
  "sub": "1234567890",
  "name": "Helen",
  "admin": true
}

Hinweis: Standardmäßig ist JWT unverschlüsselt, verwendet aber den Base64-Algorithmus. Nachdem die JWT-Zeichenfolge abgerufen wurde, kann sie wieder in die ursprünglichen JSON-Daten konvertiert werden. Jeder kann seinen Inhalt interpretieren, also erstellen Sie kein privates Informationsfeld. Beispielsweise: Das Kennwort des Benutzers muss „Kann nicht im JWT gespeichert werden“ lauten.
4.3 Signatur
        Der Signatur-Hash-Teil besteht darin, die beiden oben genannten Teile der Daten zu signieren. Außerdem müssen die Base64-codierten Header- und Nutzdaten verwendet werden, um über den angegebenen Algorithmus einen Hash zu generieren, um sicherzustellen, dass die Daten nicht manipuliert werden. Zuerst müssen Sie einen Schlüssel angeben. Dieser Schlüssel wird nur auf dem Server gespeichert und kann nicht an Benutzer weitergegeben werden. Verwenden Sie dann den im Header angegebenen Signaturalgorithmus, um eine Signatur zu generieren. Nachdem der Signatur-Hash berechnet wurde, bilden die drei Teile des JWT-Headers, der Nutzlast und des Signatur-Hashs eine Zeichenfolge, und jeder Teil wird durch . getrennt, um das gesamte JWT-Objekt zu bilden.

Achten Sie auf die Rolle jedes Teils von JWT, nachdem der Server das vom Client gesendete JWT-Token empfangen hat:

  • Der Header und die Nutzlast können Base64 direkt verwenden, um den Originaltext zu analysieren, den Hash-Signaturalgorithmus aus dem Header abzurufen und gültige Daten aus der Nutzlast abzurufen.
  • Da die Signatur einen irreversiblen Verschlüsselungsalgorithmus verwendet, kann der Originaltext nicht analysiert werden. Seine Funktion besteht darin, zu überprüfen, ob das Token manipuliert wurde. Nachdem der Server den Verschlüsselungsalgorithmus im Header erhalten hat, verwendet er den Algorithmus und den SecretKey, um den Header und die Nutzdaten zu verschlüsseln, und vergleicht, ob die verschlüsselten Daten mit den vom Client gesendeten übereinstimmen. Beachten Sie, dass der SecretKey nur auf dem Server gespeichert werden kann und seine Bedeutung für verschiedene Verschlüsselungsalgorithmen unterschiedlich ist. Im Allgemeinen stellt der SecretKey für den MD5-Digest-Verschlüsselungsalgorithmus tatsächlich den Salt-Wert dar.

5. Arten von JWT

        Tatsächlich bezieht sich JWT (JSON Web Token) auf eine Spezifikation, die es uns ermöglicht, JWT zum sicheren und zuverlässigen Übertragen von Informationen zwischen zwei Organisationen zu verwenden. Die spezifische Implementierung von JWT kann in die folgenden Typen unterteilt werden:

  • Unsicheres JWT: unsigniertes, unsicheres JWT
  • JWS: signiert JWT
  • JWE: Das verschlüsselte JWT des Nutzlastteils

5.1 Nicht sicheres JWT
Signiertes JWT wird nicht verwendet, dh unsicheres JWT. Der Header-Teil gibt den Signaturalgorithmus nicht an und es gibt keinen Signature-Teil.
5.2 JWS
        JWS, also JWT-Signatur, basiert auf der Struktur des vorherigen nicht sicheren JWT, der Signaturalgorithmus wird im Header deklariert und die Signatur wird am Ende hinzugefügt. Durch das Erstellen einer Signatur soll sichergestellt werden, dass JWT nicht von anderen manipuliert werden kann. Das JWT, das wir normalerweise verwenden, ist im Allgemeinen JWS. Zur Vervollständigung der Signatur wird neben den Header- und Payload-Informationen auch der Schlüssel des Algorithmus benötigt, der SecretKey. Im Allgemeinen gibt es zwei Arten von Verschlüsselungsalgorithmen:

  • Symmetrische Verschlüsselung: SecretKey bezieht sich auf den Verschlüsselungsschlüssel, der Signaturen generieren und Signaturen überprüfen kann
  • Asymmetrische Verschlüsselung: SecretKey bezieht sich auf den privaten Schlüssel, der nur zur Generierung einer Signatur verwendet wird und nicht zur Überprüfung der Signatur verwendet werden kann (der öffentliche Schlüssel wird zur Signaturüberprüfung verwendet).

Der Schlüssel oder das Schlüsselpaar von JWT wird im Allgemeinen als JSON Web Key oder JWK bezeichnet. Bisher gibt es drei Signaturalgorithmen für jwt:

  • HMAC [Hash Message Authentication Code (Symmetrisch)]: HS256/HS384/HS512
  • RSASSA [RSA-Signaturalgorithmus (asymmetrisch)] (RS256/RS384/RS512)
  • ECDSA [Elliptic Curve Data Signature Algorithm (Asymmetric)] (ES256/ES384/ES512)

6. Anwendung in der tatsächlichen Entwicklung

6.1 Java-JWT
führt Abhängigkeiten ein

<dependency>
    <groupId>com.auth0</groupId>
    <artifactId>java-jwt</artifactId>
    <version>3.10.3</version>
</dependency>

Token generieren

public class JWTTest {
    
    
    @Test
    public void testGenerateToken(){
    
    
        // 指定token过期时间为10秒
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.SECOND, 10);

        String token = JWT.create()
                .withHeader(new HashMap<>())  // Header
                .withClaim("userId", 21)  // Payload
                .withClaim("userName", "baobao")
                .withExpiresAt(calendar.getTime())  // 过期时间
                .sign(Algorithm.HMAC256("!34ADAS"));  // 签名用的secret

        System.out.println(token);
    }
}

Analysieren Sie die JWT-Zeichenfolge

public class JWTTest {
    
    
    @Test
    public void testGenerateToken(){
    
    
        // 指定token过期时间为10秒
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.SECOND, 10);

        String token = JWT.create()
                .withHeader(new HashMap<>())  // Header
                .withClaim("userId", 21)  // Payload
                .withClaim("userName", "baobao")
                .withExpiresAt(calendar.getTime())  // 过期时间
                .sign(Algorithm.HMAC256("!34ADAS"));  // 签名用的secret

        System.out.println(token);
    }
}

6.2 jjwt-root
führt Abhängigkeiten ein

<!-- https://mvnrepository.com/artifact/io.jsonwebtoken/jjwt -->
<dependency>
    <groupId>io.jsonwebtoken</groupId>
    <artifactId>jjwt</artifactId>
    <version>0.9.1</version>
</dependency>
public class JwtUtils {
    
    
    // token时效:24小时
    public static final long EXPIRE = 1000 * 60 * 60 * 24;
    // 签名哈希的密钥,对于不同的加密算法来说含义不同
    public static final String APP_SECRET = "ukc8BDbRigUDaY6pZFfWus2jZWLPHO";

    /**
     * 根据用户id和昵称生成token
     * @param id  用户id
     * @param nickname 用户昵称
     * @return JWT规则生成的token
     */
    public static String getJwtToken(String id, String nickname){
    
    
        String JwtToken = Jwts.builder()
                .setHeaderParam("typ", "JWT")
                .setHeaderParam("alg", "HS256")
                .setSubject("baobao-user")
                .setIssuedAt(new Date())
                .setExpiration(new Date(System.currentTimeMillis() + EXPIRE))
                .claim("id", id)
                .claim("nickname", nickname)
            	// HS256算法实际上就是MD5加盐值,此时APP_SECRET就代表盐值
                .signWith(SignatureAlgorithm.HS256, APP_SECRET)
                .compact();

        return JwtToken;
    }

    /**
     * 判断token是否存在与有效
     * @param jwtToken token字符串
     * @return 如果token有效返回true,否则返回false
     */
    public static boolean checkToken(String jwtToken) {
    
    
        if(StringUtils.isEmpty(jwtToken)) return false;
        try {
    
    
            Jwts.parser().setSigningKey(APP_SECRET).parseClaimsJws(jwtToken);
        } catch (Exception e) {
    
    
            e.printStackTrace();
            return false;
        }
        return true;
    }

    /**
     * 判断token是否存在与有效
     * @param request Http请求对象
     * @return 如果token有效返回true,否则返回false
     */
    public static boolean checkToken(HttpServletRequest request) {
    
    
        try {
    
    
            // 从http请求头中获取token字符串
            String jwtToken = request.getHeader("token");
            if(StringUtils.isEmpty(jwtToken)) return false;
            Jwts.parser().setSigningKey(APP_SECRET).parseClaimsJws(jwtToken);
        } catch (Exception e) {
    
    
            e.printStackTrace();
            return false;
        }
        return true;
    }

    /**
     * 根据token获取会员id
     * @param request Http请求对象
     * @return 解析token后获得的用户id
     */
    public static String getMemberIdByJwtToken(HttpServletRequest request) {
    
    
        String jwtToken = request.getHeader("token");
        if(StringUtils.isEmpty(jwtToken)) return "";
        Jws<Claims> claimsJws = Jwts.parser().setSigningKey(APP_SECRET).parseClaimsJws(jwtToken);
        Claims claims = claimsJws.getBody();
        return (String)claims.get("id");
    }
}

jjwt hat nach Version 0.10 große Änderungen erfahren, und es müssen mehrere Abhängigkeiten eingeführt werden

<dependency>
    <groupId>io.jsonwebtoken</groupId>
    <artifactId>jjwt-api</artifactId>
    <version>0.11.2</version>
</dependency>
<dependency>
    <groupId>io.jsonwebtoken</groupId>
    <artifactId>jjwt-impl</artifactId>
    <version>0.11.2</version>
    <scope>runtime</scope>
</dependency>
<dependency>
    <groupId>io.jsonwebtoken</groupId>
    <artifactId>jjwt-jackson</artifactId> <!-- or jjwt-gson if Gson is preferred -->
    <version>0.11.2</version>
    <scope>runtime</scope>
</dependency>

Nach der Version jjwt0.10 gelten für die Länge von SecretKey die folgenden obligatorischen Anforderungen:

  • HS256: erfordert mindestens 256 Bit (32 Byte)
  • HS384: erfordert mindestens 384 Bit (48 Byte)
  • HS512: erfordert mindestens 512 Bit (64 Byte)
  • RS256 und PS256: mindestens 2048 Bit
  • RS384 und PS384: mindestens 3072 Bit
  • RS512 und PS512: mindestens 4096 Bit
  • ES256: mindestens 256 Bit (32 Byte)
  • ES384: mindestens 384 Bit (48 Byte)
  • ES512: mindestens 512 Bit (64 Byte)

In der neuen Version von jjwt handelt es sich bei den vorherigen Signatur- und Überprüfungsmethoden ausschließlich um Zeichenfolgen des eingehenden Schlüssels, was veraltet ist. Die neueste Methode erfordert die Übergabe eines Key-Objekts.

public class JwtUtils {
    
    
    // token时效:24小时
    public static final long EXPIRE = 1000 * 60 * 60 * 24;
    // 签名哈希的密钥,对于不同的加密算法来说含义不同
    public static final String APP_SECRET = "ukc8BDbRigUDaY6pZFfWus2jZWLPHOsdadasdasfdssfeweee";

    /**
     * 根据用户id和昵称生成token
     * @param id  用户id
     * @param nickname 用户昵称
     * @return JWT规则生成的token
     */
    public static String getJwtToken(String id, String nickname){
    
    
        String JwtToken = Jwts.builder()
                .setSubject("baobao-user")
                .setIssuedAt(new Date())
                .setExpiration(new Date(System.currentTimeMillis() + EXPIRE))
                .claim("id", id)
                .claim("nickname", nickname)
                // 传入Key对象
                .signWith(Keys.hmacShaKeyFor(APP_SECRET.getBytes(StandardCharsets.UTF_8)), SignatureAlgorithm.HS256)
                .compact();
        return JwtToken;
    }

    /**
     * 判断token是否存在与有效
     * @param jwtToken token字符串
     * @return 如果token有效返回true,否则返回false
     */
    public static Jws<Claims> decode(String jwtToken) {
    
    
        // 传入Key对象
        Jws<Claims> claimsJws = Jwts.parserBuilder().setSigningKey(Keys.hmacShaKeyFor(APP_SECRET.getBytes(StandardCharsets.UTF_8))).build().parseClaimsJws(jwtToken);
        return claimsJws;
    }
}

Im eigentlichen SpringBoot-Projekt können wir uns im Allgemeinen mit dem folgenden Verfahren anmelden:

  • Nachdem die Anmeldeüberprüfung bestanden wurde, wird ein entsprechendes zufälliges Token für den Benutzer generiert (beachten Sie, dass sich dieses Token nicht auf JWT bezieht, sondern mithilfe von Algorithmen wie uuid generiert werden kann) und dieses Token dann als Teil des Schlüssels verwendet wird , die Benutzerinformationen werden in Redis als Wert gespeichert und der Ablauf wird festgelegt. Zeit, diese Ablaufzeit ist der Zeitpunkt, zu dem die Anmeldung ungültig wird
  • Verwenden Sie das in Schritt 1 generierte zufällige Token als JWT-Nutzlast, um eine JWT-Zeichenfolge zu generieren und diese an das Frontend zurückzugeben
  • Jede Anfrage nach dem Frontend trägt die JWT-Zeichenfolge im Autorisierungsfeld im Anfrageheader
  • Das Backend definiert einen Interceptor. Jedes Mal, wenn eine Frontend-Anfrage empfangen wird, wird die JWT-Zeichenfolge aus dem Autorisierungsfeld im Anforderungsheader entnommen und überprüft. Nachdem die Überprüfung bestanden wurde, wird das zufällige Token in der Nutzlast analysiert und dann das zufällige Token wird verwendet Holen Sie sich den Schlüssel und holen Sie sich die Benutzerinformationen von Redis. Wenn Sie sie erhalten können, bedeutet dies, dass sich der Benutzer angemeldet hat
public class JWTInterceptor implements HandlerInterceptor {
    
    
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
    
    
        String JWT = request.getHeader("Authorization");
        try {
    
    
            // 1.校验JWT字符串
            DecodedJWT decodedJWT = JWTUtils.decode(JWT);
            // 2.取出JWT字符串载荷中的随机token,从Redis中获取用户信息
            ...
            return true;
        }catch (SignatureVerificationException e){
    
    
            System.out.println("无效签名");
            e.printStackTrace();
        }catch (TokenExpiredException e){
    
    
            System.out.println("token已经过期");
            e.printStackTrace();
        }catch (AlgorithmMismatchException e){
    
    
            System.out.println("算法不一致");
            e.printStackTrace();
        }catch (Exception e){
    
    
            System.out.println("token无效");
            e.printStackTrace();
        }
        return false;
    }
}

Ich denke du magst

Origin blog.csdn.net/m0_73845616/article/details/127603451
Empfohlen
Rangfolge