Spring Cloud of springcloud+springcloud+vue+uniapp distributed micro service E-commerce mall creates a unified authentication service based on JWT

Posted by vcv on Thu, 03 Mar 2022 21:22:10 +0100

The authentication service must have user information, otherwise how to authenticate whether it is a legal user? Because it is an internal call authentication, it can be simpler. Database management is one way. User configuration or distributed information can be perfectly integrated.

Table structure

The case in this tutorial omits the step of checking the database. You can supplement it by yourself, but the design of the table still needs to be explained to you. The form of user table is shown in Figure 1.

The relevant codes are shown below.

create table auth_user(
  id int(4) not null,
  accessKey varchar(100) not null,
  secretKey varchar(100) not null,
  Primary key (id)
);
Alter table auth_user comment 'Authentication user information form';

There are only a few simple fields here. If you have other needs, you can expand them by yourself. The accessKey and secretKey in the code are the identity of the user.

JWT tool class encapsulation

The GitHub address of JWT is: https://github.com/jwtk/jjwt , the dependency configuration code is as follows.

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

There are mainly the following methods for certification with tools:

  • Generate Token.
  • Check whether the Token is legal.
  • Refresh RSA public key and private key.


Generating a Token is to generate a Token through the user's ID after user authentication. This Token is encrypted by RSA encryption. The content of the Token includes the user's ID and expiration time.

Checking the Token is to check whether it is a legal user according to the Token brought by the caller, that is, decrypt the Token, decrypt it and indicate it is legal within the validity period, and return the user ID if it is legal.

The function of refreshing RSA public key and private key is to prevent the disclosure of public key and private key. Public key and private key are generally written dead, but we can make configuration. After integrating the configuration management center, you can dynamically modify the public key and private key. After modification, you need to re initialize the object information of the public key and private key.

The code for obtaining Token is as follows.

/**
* Get Token
*
* @param uid User ID
* @param exp Failure time, in minutes
* @return
*/
public static String getToken(String uid, int exp) {
    Long endTime = System.currentTimeMillis() + 1000 * 60 * exp;
    return Jwts.builder().setSubject(uid).setExpiration(new Date(endTime))
            .signWith(SignatureAlgorithm.RS512, priKey).compact();
}

Check whether the Token is legal. The code is as follows.

/**
* Check whether the Token is legal
*
* @param token
* @return JWTResult
*/
public JWTResult checkToken(String token) {
    try {
        Claims claims = Jwts.parser().setSigningKey(pubKey).parseClaimsJws(token).getBody();
        String sub = claims.get("sub", String.class);
        return new JWTResult(true, sub, "Legal request", ResponseCode.SUCCESS_CODE.getCode());
    } catch (ExpiredJwtException e) {
        // When parsing JWT strings, if the 'expiration time field' is earlier than the current time,
        // An ExpiredJwtException will be thrown, indicating that the request has expired
        return new JWTResult(false, null, "token Expired  ", ResponseCode.TOKEN_TIMEOUT_CODE.getCode());
    } catch (SignatureException e) {
        // When parsing JWT string, if the key is incorrect, the parsing will fail and an error will be thrown
        // The SignatureException exception indicates that the JWT string is forged
        return new JWTResult(false, null, "Illegal request", ResponseCode.NO_AUTH_CODE.getCode());
    } catch (Exception e) {
        return new JWTResult(false, null, "Illegal request", ResponseCode.NO_AUTH_CODE.getCode());
    }
}

The complete code is shown below.

/**
* API RSA authentication is used to call encryption tools
*/
public class JWTUtils {
    private static RSAPrivateKey priKey;
    private static RSAPublicKey pubKey;
    private static class SingletonHolder {
        private static final JWTUtils INSTANCE = new JWTUtils();
    }
    public synchronized static JWTUtils getInstance(String modulus, String privateExponent, String publicExponent) {
        if (priKey == null && pubKey == null) {
            priKey = RSAUtils.getPrivateKey(modulus, privateExponent);
            pubKey = RSAUtils.getPublicKey(modulus, publicExponent);
        }
        return SingletonHolder.INSTANCE;
    }
    public synchronized static void reload(String modulus, String privateExponent, String publicExponent) {
        priKey = RSAUtils.getPrivateKey(modulus, privateExponent);
        pubKey = RSAUtils.getPublicKey(modulus, publicExponent);
    }
    public synchronized static JWTUtils getInstance() {
        if (priKey == null && pubKey == null) {
            priKey = RSAUtils.getPrivateKey(RSAUtils.modulus, RSAUtils.private_exponent);
            pubKey = RSAUtils.getPublicKey(RSAUtils.modulus, RSAUtils.public_exponent);
        }
        return SingletonHolder.INSTANCE;
    }
    /**
     * Get Token
     *
     * @param uid User ID
     * @param exp Failure time, in minutes
     * @return
     */
    public static String getToken(String uid, int exp) {
        long endTime = System.currentTimeMillis() + 1000 * 60 * exp;
        return Jwts.builder().setSubject(uid).setExpiration(new Date(endTime))
                .signWith(SignatureAlgorithm.RS512, priKey).compact();
    }
    /**
     * Get Token
     *
     * @param uid User ID
     * @return
     */
    public String getToken(String uid) {
        long endTime = System.currentTimeMillis() + 1000 * 60 * 1440;
        return Jwts.builder().setSubject(uid).setExpiration(new Date(endTime))
                .signWith(SignatureAlgorithm.RS512, priKey).compact();
    }
    /**
     * Check whether the Token is legal
     *
     * @param token
     * @return JWTResult
     */
    public JWTResult checkToken(String token) {
        try {
            Claims claims = Jwts.parser().setSigningKey(pubKey).parseClaimsJws(token).getBody();
            String sub = claims.get("sub", String.class);
            return new JWTResult(true, sub, "Legal request", ResponseCode.SUCCESS_CODE.getCode());
        } catch (ExpiredJwtException e) {
            // When parsing the JWT string, if the 'expiration time field' is earlier than the current time, an ExpiredJwtException will be thrown, indicating that the request has expired
            return new JWTResult(false, null, "token Expired ", ResponseCode.TOKEN_TIMEOUT_CODE.getCode());
        } catch (SignatureException e) {
            // When parsing the JWT string, if the key is incorrect, the parsing will fail and a SignatureException exception will be thrown, indicating that the JWT string is forged
            return new JWTResult(false, null, "Illegal request", ResponseCode.NO_AUTH_CODE.getCode());
        } catch (Exception e) {
            return new JWTResult(false, null, "Illegal request", ResponseCode.NO_AUTH_CODE.getCode());
        }
    }
    public static class JWTResult {
        private boolean status;
        private String uid;
        private String msg;
        private int code;
        public JWTResult() {
            super();
        }
        public JWTResult(boolean status, String uid, String msg, int code) {
            super();
            this.status = status;
            this.uid = uid;
            this.msg = msg;
            this.code = code;
        }
        public int getCode() {
            return code;
        }
        public void setCode(int code) {
            this.code = code;
        }
        public String getMsg() {
            return msg;
        }
        public void setMsg(String msg) {
            this.msg = msg;
        }
        public boolean isStatus() {
            return status;
        }
        public void setStatus(boolean status) {
            this.status = status;
        }
        public String getUid() {
            return uid;
        }
        public void setUid(String uid) {
            this.uid = uid;
        }
    }
}

Authentication interface

The authentication interface is used for the caller to authenticate. If the authentication passes, an encrypted Token will be returned to the other party, and the other party can use the Token to request other services. The authentication Token code is as follows.

@PostMapping("/token")
public ResponseData auth(@RequestBody AuthQuery query) throws Exception {
    if (StringUtils.isBlank(query.getAccessKey()) || StringUtils.isBlank(query.getSecretKey())) {
        return ResponseData.failByParam("accessKey and secretKey not null");
    }
    User user = authService.auth(query);
    if (user == null) {
        return ResponseData.failByParam(" Authentication failed ");
    }
    JWTUtils jwt = JWTUtils.getInstance();
    return ResponseData.ok(jwt.getToken(user.getId().toString()));
}

The certification parameter codes are shown below.

/**
* API User authentication parameter class
*/
public class AuthQuery {
    private String accessKey;
    private String secretKey;
    // get set ...
}

auth method in AuthService is to judge whether there is this user according to accessKey and secretKey.

Recommended e-commerce source code

Topics: github Vue.js Spring Cloud jwt uni-app