1. JWT test

/ * * *@Auther: csp1999
 * @Date: 2021/01/24 / do *@Description: JWT test */
public class JwtTest {

    ** Jwt = Header + payload + signature */
    @Test
    public void testCreateJwt(a) {
        // Build the JWT token
        Header: Describes the most basic information about the JWT, such as its type and the algorithm used to sign it
        JwtBuilder builder = Jwts.builder()
                .setId("8989")                      // Set the unique token number
                .setIssuer("csp1999")               // Sets the token issuer
                .setSubject("JWT encryption Test")           // Set the token subject to be JSON data
                .setIssuedAt(new Date())            // Set the token issuing date
                .setExpiration(new Date(System.currentTimeMillis() + 1000 * 60 * 3));// Set the token expiration time to 3 minutes

        // 2. Custom load playload: a place to store valid information
        Map<String,Object> userInfo = new HashMap<>();
        userInfo.put("username"."csp");
        userInfo.put("password"."123456");
        userInfo.put("school".Henan University of Science and Technology);
        userInfo.put("age"."22");
        // Add the payload to the JWT token
        builder.addClaims(userInfo);

        // 3. Set the signature for the token
        builder.signWith(SignatureAlgorithm.HS256, "haust");// Set the token signature to use the HS256 algorithm and set the SecretKey key (string)

        // Construct and return a string
        String jwtStr = builder.compact();
        System.out.println(jwtStr);
    }

    /** * parse Jwt token data */
    @Test
    public void testParseJwt(a) {
        // JWT string
        String jwtStr = "eyJhbGciOiJIUzI1NiJ9.eyJqdGkiOiI4OTg5IiwiaXNzIjoiY3NwMTk5OSIsInN1YiI6IkpXVOWKoOWvhua1i-ivlSIsImlhdCI6MTYxMTQ4ODc1MSwiZX hwIjoxNjExNDg4OTMxLCJwYXNzd29yZCI6IjEyMzQ1NiIsInNjaG9vbCI6Iuays-WNl-enkeaKgOWkp-WtpiIsImFnZSI6IjIyIiwidXNlcm5hbWUiOiJjc3 AifQ.uH28G9MSHfzaKBAOyr8AdksYLVvy8O5P8g7TORZIUFY";

        // Parse JWT strings
        Claims claims = Jwts.parser().
                setSigningKey("haust").     // Key (salt)
                parseClaimsJws(jwtStr).     // The token object to parse
                getBody();                  // Get the parsed result

        // {jti=8989, iss= CSP1999, sub=JWT encryption test, IAT =1611488751, exp=1611488931, password=123456, school= School, age=22, username=csp}System.out.println(claims); }}Copy the code

2. JWT tool classes

/ * * *@Auther: csp1999
 * @Date: 2021/01/24 / do *@Description: JWT tool class */
public class JwtUtil {
    // Valid for
    public static final Long JWT_TTL = 3600000L;// 60 * 60 * 1000 per hour

    // Jwt token information
    public static final String JWT_KEY = "itcast";

    /** * Generate token *@param id
     * @param subject
     * @param ttlMillis
     * @return* /
    public static String createJWT(String id, String subject, Long ttlMillis) {
        // Specify the algorithm
        SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;

        // The current system time
        long nowMillis = System.currentTimeMillis();
        // Token issue time
        Date now = new Date(nowMillis);

        // If the token validity period is null, the default validity period is 1 hour
        if (ttlMillis == null) {
            ttlMillis = JwtUtil.JWT_TTL;
        }

        // Token expiration time Settings
        long expMillis = nowMillis + ttlMillis;
        Date expDate = new Date(expMillis);

        // Generate a secret key
        SecretKey secretKey = generalKey();

        // Encapsulate Jwt token information
        JwtBuilder builder = Jwts.builder()
                .setId(id)                                  // Unique ID
                .setSubject(subject)                        // Themes can be JSON data
                .setIssuer("admin")                         / / issue
                .setIssuedAt(now)                           // Issue time
                .signWith(signatureAlgorithm, secretKey)    // Signature algorithm and key
                .setExpiration(expDate);                    // Set the expiration time

        return builder.compact();
    }

    /** * Generate encrypted secretKey **@return* /
    public static SecretKey generalKey(a) {
        byte[] encodedKey = Base64.getEncoder().encode(JwtUtil.JWT_KEY.getBytes());
        SecretKey key = new SecretKeySpec(encodedKey, 0, encodedKey.length, "AES");
        return key;
    }


    /** * parse token data **@param jwt
     * @return
     * @throws Exception
     */
    public static Claims parseJWT(String jwt) throws Exception {
        SecretKey secretKey = generalKey();
        return Jwts.parser()
                .setSigningKey(secretKey)
                .parseClaimsJws(jwt)
                .getBody();
    }

    public static void main(String[] args) {
        String jwt = JwtUtil.createJWT("weiyibiaoshi"."aaaaaa".null);

        System.out.println(jwt);
        try {
            Claims claims = JwtUtil.parseJWT(jwt);
            System.out.println(claims);
        } catch(Exception e) { e.printStackTrace(); }}}Copy the code

3. Verify user login

3.1 Gateway Filter

/ * * *@Auther: csp1999
 * @Date: 2021/01/24/20:17
 * @Description: Authorization filter */
@Component
public class AuthorizeFilter implements GlobalFilter.Ordered {

    // The token header name
    private static final String AUTHORIZE_TOKEN = "Authorization";

    /** * global filter **@param exchange
     * @param chain
     * @return* /
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        // Get the Request and Response objects
        ServerHttpRequest request = exchange.getRequest();
        ServerHttpResponse response = exchange.getResponse();

        // Get the request URI
        String path = request.getURI().getPath();

        // If it is an open micro-service such as login and GOODS [goods is partially open here], it will be directly released. The complete demonstration is not done here, and a permission system needs to be designed for the complete demonstration
        // Only login and search are allowed
        if (path.startsWith("/api/user/login") || path.startsWith("/api/brand/search/")) {
            / / release
            Mono<Void> filter = chain.filter(exchange);

            return filter;
        }

        // Token information obtained from the initial file
        String token = request.getHeaders().getFirst(AUTHORIZE_TOKEN);
        // If true: indicates that the token is in the header file. False: indicates that the token is not in the header file
        boolean hasToken = true;

        // If there is no token information in the header file, get it from the request parameters
        if (StringUtils.isEmpty(token)) {
            token = request.getQueryParams().getFirst(AUTHORIZE_TOKEN);
            hasToken = false;
        }

        // If null, an error code is printed
        if (StringUtils.isEmpty(token)) {
            // Set method not allowed to be accessed, 405 error code
            response.setStatusCode(HttpStatus.METHOD_NOT_ALLOWED);
            return response.setComplete();
        }

        // If not empty, the token data is parsed
        try {
            Claims claims = JwtUtil.parseJWT(token);
        } catch (Exception e) {
            e.printStackTrace();
            // Parsing failed, response 401 error
            response.setStatusCode(HttpStatus.UNAUTHORIZED);
            return response.setComplete();
        }

        // Encapsulate the token in the header file before releasing it (this step is to facilitate AUTH2 validation of the token)
        request.mutate().header(AUTHORIZE_TOKEN,token);

        / / release
        return chain.filter(exchange);
    }


    /** * Filter execution order **@return* /
    @Override
    public int getOrder(a) {
        / / the first
        return 0; }}Copy the code

3.2 Gateway microservice application.yml

spring:
  cloud:
    gateway:
      globalcors:
        corsConfigurations:
          '[/ * *]': Match all requests
            allowedOrigins: "*" # Cross-domain processing allows all domains
            allowedMethods: Request types supported
              - GET
              - POST
              - PUT
              - DELETE
      routes:
        Configure the goods micro-service route for docking
        - id: changgou_goods_route
          uri: lb://changgou-goods
          predicates:
            - Path=/api/brand/**,/api/category/**
          filters:
            - StripPrefix=1
            - name: RequestRateLimiter Use the default facatory
              args:
                The Bean object name for the parser of the key used for limiting the flow. It uses SpEL expressions to get Bean objects from the Spring container based on #{@beanname}.
                key-resolver: "#{@ipKeyResolver}"
                # average token bucket fill rate per second
                redis-rate-limiter.replenishRate: 1
                Total token bucket capacity
                redis-rate-limiter.burstCapacity: 1
                The token bucket fills at a rate of 1 token per second.
        Configure the micro-service route for the interconnection user user
        - id: changgou_user_route
          uri: lb://changgou-user
          predicates:
            - Path=/api/user/**,/api/address/**,/api/areas/**,/api/cities/**,/api/provinces/**
          filters:
            There is no/API in the real request for the user micro service, so here StripPrefix=1
            - StripPrefix=1
  # Micro service name
  application:
    name: changgou-gateway-web
  # Redis configuration
  redis:
    # Redis database index (default 0)
    database: 0
    # Redis server address
    host: 8.13166.136.
    # Redis server connection port
    port: 6379
    # Redis server connection password (default null)
    password: csp19990129

server:
  port: 8001
eureka:
  client:
    service-url:
      defaultZone: http://127.0.0.1:7001/eureka
  instance:
    prefer-ip-address: true
management:
  endpoint:
    gateway:
      enabled: true
    web:
      exposure:
        include: true
Copy the code

3.3 Gateway Microservices master startup class

/ * * *@Auther: csp1999
 * @DateBetter: 2021/01/24 / *@Description: User/foreground microservices gateway startup class */
@SpringBootApplication
@EnableEurekaClient
public class GatewayWebApplication {

    public static void main(String[] args) {
        SpringApplication.run(GatewayWebApplication.class, args);
    }

    /** * IP traffic limiting: Creates a unique user ID based on the requested IP address, and performs traffic limiting operations based on the IP address **@return* /
    @Bean(name = "ipKeyResolver")
    public KeyResolver userKeyResolver(a) {
        return new KeyResolver() {
            @Override
            public Mono<String> resolve(ServerWebExchange exchange) {
                // Obtain the IP address of the remote client
                String hostName = exchange.getRequest().getRemoteAddress().getAddress().getHostAddress();
                System.out.println("hostName:" + hostName);
                returnMono.just(hostName); }}; }}Copy the code

3.4 User microservices Write login codes

/ * * *@Author: csp1999
 * @Description: User's Controller *@Date2021/1/14 0:18 * /
@RestController
@RequestMapping("/user")
@CrossOrigin
public class UserController {

    @Autowired
    private UserService userService;

	 /*** * Modify User data *@param user
     * @param id
     * @return* /
    @PutMapping(value = "/{id}")
    public Result update(@RequestBody User user, @PathVariable String id) {... }/*** * Add User data *@param user
     * @return* /
    @PostMapping
    public Result add(@RequestBody User user) {... }/*** * Query User data by ID *@param id
     * @return* /
    @GetMapping("/{id}")
    public Result<User> findById(@PathVariable String id) {... }/*** * Query all User data *@return* /
    @GetMapping
    public Result<List<User>> findAll() {
       ...
    }

    /*** * user login *@param username
     * @param password
     * @param response
     * @param request
     * @return* /
    @RequestMapping("/login")
    public Result<User> login(String username, String password, HttpServletResponse response, HttpServletRequest request) {
        // 1. Query the object corresponding to the user name in the database
        User user = userService.findById(username);
        if (user == null) {
            // 2. Check whether the user is null
            return new Result<User>(false, StatusCode.LOGINERROR, "Wrong username or password...");
        }

        // 3. If the password is not empty, check whether the password is correct. If yes, the login succeeds
        if (BCrypt.checkpw(password, user.getPassword())) {
            // Successful login, save user information to map
            Map<String, Object> info = new HashMap<String, Object>();
            info.put("role"."USER");
            info.put("success"."SUCCESS");
            info.put("username", username);

            // 3.1 Generate tokens
            String jwt = JwtUtil.createJWT(UUID.randomUUID().toString(), JSON.toJSONString(info), null);
            // 3.2 Set JWT to store cookies
            Cookie cookie = new Cookie("Authorization", jwt);
            response.addCookie(cookie);
            // 3.3 Set JWT to save to header file
            response.setHeader("Authorization", jwt);

            return new Result<User>(true, StatusCode.OK, "Login successful", jwt);
        } else {
            // Login failed
            return new Result<User>(false, StatusCode.LOGINERROR, "Wrong username or password"); }}}Copy the code