《项目实战》构建SpringCloud alibaba项目(二、构建微服务鉴权子工程store-authority-service)

系列文章目录

构建SpringCloud alibaba项目(一、构建父工程、公共库、网关)
构建SpringCloud alibaba项目(二、构建微服务鉴权子工程store-authority-service)


文章目录


前言

构建微服务鉴权子工程store-authority-service,集成JWT,提供权限验证功能。


1、在公共库增加 UserInfo类

微服务鉴权子工程,需要用到用户信息类,存放在JWT生成的Token信息里。

java 复制代码
package com.kelvin.common.entity;

import lombok.Data;

/***
 * @title UserInfo
 * @desctption <TODO description class purpose>
 * @author Administrator
 * @create 2023/6/19 17:05
 **/
@Data
public class UserInfo {

    private long id;

    private String userAccount;

    private String userName;

    private String pwd;

}

2、微服务鉴权子工程store-authority-service

2.1、创建子工程store-authority-service

创建Module,store-authority-service

2.2、修改pom.xml配置

加入依赖:springboot、JWT、nacos-discovery、公共库等

java 复制代码
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>com.kelvin</groupId>
        <artifactId>onlinestore</artifactId>
        <version>1.0-SNAPSHOT</version>
    </parent>

    <artifactId>store-authority-service</artifactId>
    <packaging>jar</packaging>

    <name>authority-service</name>
    <url>http://maven.apache.org</url>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

    <dependencies>

        <dependency>
            <groupId>io.jsonwebtoken</groupId>
            <artifactId>jjwt</artifactId>
            <version>0.7.0</version>
        </dependency>
        <dependency>
            <groupId>com.auth0</groupId>
            <artifactId>java-jwt</artifactId>
            <version>3.4.0</version>
        </dependency>
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>


        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-autoconfigure</artifactId>
        </dependency>

        <dependency>
            <groupId>com.kelvin</groupId>
            <artifactId>store-common</artifactId>
        </dependency>

        <dependency>
            <groupId>com.google.code.gson</groupId>
            <artifactId>gson</artifactId>
            <version>2.7</version>
        </dependency>
   
    </dependencies>
</project>

2.3、修改application.yml配置

java 复制代码
server:
  port: 7777
spring:
  application:
    name: store-auth-service
  cloud:
    nacos:
      discovery:
        server-addr: localhost:8848  #Nacos server 的地址
config:
  jwt:
    # 加密密钥
    secret: kelvin
    # token有效时长
    expire: 200
    # header 名称
    header: token

2.4、配置JWT

java 复制代码
package com.kelvin.authority.config;

/***
 * @title JwtConfig
 * @desctption JWT配置类
 * @author kelvin
 * @create 2023/6/8 9:39
 **/
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
import java.util.Date;

@Component
@ConfigurationProperties(prefix = "config.jwt")
@Data
public class JwtConfig {
    /**
     * 密钥
     */
    private String secret;
    /**
     * 过期时间
     */
    private Long expire;
    /**
     * 头部
     */
    private String header;

    /**
     * 生成token
     * @param subject
     * @return
     */
    public String createToken(String subject){
        Date nowDate = new Date();
        Date expireDate = new Date(nowDate.getTime() + expire * 1000);

        return Jwts.builder()
                .setHeaderParam("typ","JWT")
                .setSubject(subject)
                .setIssuedAt(nowDate)
                .setExpiration(expireDate)
                .signWith(SignatureAlgorithm.HS512,secret)
                .compact();

    }

    /**
     * 获取token中的注册信息
     * @param token
     * @return
     */
    public Claims getTokenClaim(String token){
        try{
            return Jwts.parser().setSigningKey(secret).parseClaimsJws(token).getBody();
        }catch (Exception e){
            return null;
        }

    }

    /**
     * 验证token是否过期
     * @param expirationTime
     * @return
     */
    public boolean isTokenExpired(Date expirationTime){
        if(null == expirationTime){
            return true;
        }else{
            return expirationTime.before(new Date());
        }
    }

    /**
     * 获取token的失效时间
     * @param token
     * @return
     */
    public Date getExpirationDateFromToken(String token){
        Claims tokenClaim = this.getTokenClaim(token);
        if(tokenClaim == null){
            return null;
        }else{
            return this.getTokenClaim(token).getExpiration();
        }

    }

    /**
     * 获取token中的用户名
     * @param token
     * @return
     */
    public String getUserNameFromToken(String token){
        return this.getTokenClaim(token).getSubject();
    }

    /**
     * 获取token中发布时间
     * @param token
     * @return
     */
    public Date getIssuedDateFromToken(String token){
        return this.getTokenClaim(token).getIssuedAt();
    }

}

2.5、编写JWT测试类

java 复制代码
package com.kelvin.authority.test;

import com.google.gson.Gson;
import com.kelvin.authority.config.JwtConfig;
import com.kelvin.common.entity.UserInfo;

/***
 * @title JwtMain
 * @desctption JWT本地测试类
 * @author Administrator
 * @create 2023/6/8 15:04
 **/
public class JwtMain {

    public static void main(String[] args) {

        JwtConfig jwtConfig = new JwtConfig();
        jwtConfig.setExpire(10L);
        jwtConfig.setSecret("kelvin");
        jwtConfig.setHeader("token");

        UserInfo userInfo = new UserInfo();
        userInfo.setId(10000000001L);
        userInfo.setUserAccount("zhangsan");
        userInfo.setUserName("张三");

        String token = jwtConfig.createToken(new Gson() .toJson(userInfo));
        System.out.println("token: " + token);

        boolean aBoolean = jwtConfig.isTokenExpired(jwtConfig.getExpirationDateFromToken(token));
        System.out.println("aBoolean: " + aBoolean);

        System.out.println( "user: " +   jwtConfig.getUserNameFromToken(token));

    }
}

2.5.1、运行结果

java 复制代码
token: eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJ7XCJpZFwiOjEwMDAwMDAwMDAxLFwidXNlckFjY291bnRcIjpcInpoYW5nc2FuXCIsXCJ1c2VyTmFtZVwiOlwi5byg5LiJXCJ9IiwiaWF0IjoxNjg3MTY2MTc1LCJleHAiOjE2ODcxNjYxODV9.KZz-WrpslG3MOKyVd_9MXofCMh3STOvR3IwseRslreuYAS56UGuBBV6qVkHErLxxy3ELlRkWpiPZBj5eyFn2fw

aBoolean: false

user: {"id":10000000001,"userAccount":"zhangsan","userName":"张三"}

2.6、对外发布鉴权API - AuthController

  • 提供【登录】接口,返回token信息
  • 提供【token是否过期】接口,返回是否过期
java 复制代码
package com.kelvin.authority.controller;

/***
 * @title AuthController
 * @desctption 用户鉴权API
 * @author Kelvin
 * @create 2023/6/8 9:40
 **/
import com.kelvin.authority.config.JwtConfig;
import com.kelvin.common.dto.TokenDTO;
import com.kelvin.common.entity.UserInfo;
import com.kelvin.common.http.HttpResultGenerator;
import com.kelvin.common.http.ResultDTO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.HashMap;
import java.util.Map;
@CrossOrigin("*")
@RestController
@RequestMapping("/auth")
public class AuthController {
    @Autowired
    private JwtConfig jwtConfig;
    @PostMapping("/login")
    public ResultDTO login(@RequestBody UserInfo userInfo){
        String token = jwtConfig.createToken(userInfo.getUserAccount());
        Map<String, String> map = new HashMap<String, String>();
        map.put("token",token);
        return HttpResultGenerator.success(map);
    }

    /**
     * token是否过期
     * @param token
     * @return
     */
    @PostMapping("/isTokenExpiration")
    public Boolean isTokenExpiration(@RequestBody TokenDTO token){
        return this.jwtConfig.isTokenExpired(this.jwtConfig.getExpirationDateFromToken(token.getToken()));
    }
}

总结

以上就是今天要讲的内容,本文简单介绍了JWT的使用,对外提供提供【登录接口】、【token是否过期接口】,为分布式系统提供鉴权微服务功能。

相关推荐
王彬泽5 小时前
【微服务】组件、基础工程构建(day2)
微服务
Cikiss5 小时前
微服务实战——SpringCache 整合 Redis
java·redis·后端·微服务
Cikiss5 小时前
微服务实战——平台属性
java·数据库·后端·微服务
杨荧8 小时前
【JAVA开源】基于Vue和SpringBoot的洗衣店订单管理系统
java·开发语言·vue.js·spring boot·spring cloud·开源
攸攸太上9 小时前
JMeter学习
java·后端·学习·jmeter·微服务
妍妍的宝贝10 小时前
k8s 中微服务之 MetailLB 搭配 ingress-nginx 实现七层负载
nginx·微服务·kubernetes
架构师吕师傅12 小时前
性能优化实战(三):缓存为王-面向缓存的设计
后端·微服务·架构
sdg_advance14 小时前
Spring Cloud之OpenFeign的具体实践
后端·spring cloud·openfeign
王彬泽14 小时前
【微服务】服务注册与发现、分布式配置管理 - Nacos
微服务·服务注册与发现·分布式配置管理
杨荧15 小时前
【JAVA开源】基于Vue和SpringBoot的旅游管理系统
java·vue.js·spring boot·spring cloud·开源·旅游