当前位置: 首页 > article >正文

项目二技巧一

目录

nginx实现根据域名来访问不同的ip端口

配置Maven私服

快照版和发布版的区别

快照版本(Snapshot)

发布版本(Release)

 导入发布版的父工程

理清楚授权规则

一.首先浏览器发送/manager/**路径请求

 第二步:构造了TokenGatewayFilter方法,并把myConfig对象和当前过滤器对象作为参数传入

第三步:执行了filter方法并校验是否为放行path

第四步:执行AuthFilter的check方法,检验票据的合法性

第五步:执行AuthFilter的auth方法,进行鉴权

第六步:放行

完整的TokenGateWayFilter类

权限管家的api使用


nginx实现根据域名来访问不同的ip端口

nginx.conf配置文件的内容

在server_name中书写域名的名字,只要访问域名的根路径就会把请求反向代理到

proxy_pass http://127.0.0.1:10880 ip端口上

  1. proxy_set_header Host $host;:这行配置设置了代理请求的Host头部,将其设置为原始请求中的Host头部。

  2. proxy_set_header X-Real-IP $remote_addr;:这行配置设置了X-Real-IP头部,将其设置为客户端的IP地址。

  3. proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;:这行配置设置了X-Forwarded-For头部,用于添加客户端的IP地址到现有的X-Forwarded-For头部中,这对于跟踪客户端的真实IP地址在代理环境中非常有用。

http {
    include       mime.types;
    default_type  application/octet-stream;
    sendfile        on;
    keepalive_timeout  65;
    server {
        listen       80;
        server_name  git.sl-express.com;
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }

        location / {
            client_max_body_size  1024m;
            proxy_connect_timeout 300s;
            proxy_send_timeout 300s;
            proxy_read_timeout 300s;
            proxy_pass http://127.0.0.1:10880;
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        }

    }

    server {
        listen       80;
        server_name  maven.sl-express.com;
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }

       
        location / {
            client_max_body_size  300m;
            proxy_connect_timeout 300s;
            proxy_send_timeout 300s;
            proxy_read_timeout 300s;
            proxy_pass http://127.0.0.1:8081;
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        }
    }

这里由于nginx在linux虚拟机上运行,如果我们需要在主机上根据域名来访问虚拟机上的不同ip端口时,需要编写hosts文件的内容

hosts文件所在目录

C:\Windows\System32\drivers\etc

 编写以下内容

192.168.150.101 git.sl-express.com
192.168.150.101 maven.sl-express.com

 这样一来在主机访问git.sl-express.com域名时,就会访问192.168.150.101这个虚拟机的ip,nginx就会根据nginx.conf配置文件的内容反向代理到虚拟机本地的http://127.0.0.1:10880ip端口

配置Maven私服

 Maven 私服(也称为 Maven 仓库管理器)是一个本地的 Maven 仓库,用于存储和管理 Maven 项目依赖的远程仓库中的项目。配置 Maven 私服可以提高构建速度,减少网络延迟,并且可以对依赖进行更好的控制。

配置完成后,当你运行 Maven 构建时,Maven 会首先检查私服中是否有所需的依赖,如果没有,才会从远程仓库下载。

我们可以在私服的 Web 界面中管理依赖,包括上传、下载、删除等操作。

 配置私服

settings.xml文件

在<servers>标签中子标签<server>中配置私服的用户名和密码

<id>sl-releases</id>:这个标签定义了服务器的唯一标识符(ID),在 Maven 的其他配置中,可以通过这个 ID 引用这个服务器配置。例如,在 pom.xml 文件中配置部署或发布时,可以使用这个 ID 来指定要部署到的服务器。
<username>deployment</username>:这个标签定义了访问服务器时使用的用户名。
<password>deployment123</password>:这个标签定义了访问服务器时使用的密码。

<servers>
        <server>
            <id>sl-releases</id>
            <username>deployment</username>
            <password>deployment123</password>
        </server>
        <server>
            <id>sl-snapshots</id>
            <username>deployment</username>
            <password>deployment123</password>
        </server>
    </servers>

mirror镜像,如果私服里没有相关的依赖,就去远程仓库里拉取对应的依赖

 <!-- 使用阿里云maven镜像,排除私服资源库 -->
    <mirrors>
        <mirror>
            <id>mirror</id>
            <mirrorOf>central,jcenter,!sl-releases,!sl-snapshots</mirrorOf>
            <name>mirror</name>
            <url>https://maven.aliyun.com/nexus/content/groups/public</url>
        </mirror>
    </mirrors> 

  1. <profiles> 标签

    • 这个标签是一个容器,用于包含多个 <profile> 配置。
  2. <profile> 配置

    • <id>sl</id>:这个标签定义了配置文件的唯一标识符(ID),在 Maven 命令中可以通过 -P 参数来激活这个 profile。
  3. <properties> 标签

    • 这个标签用于定义一些属性,这些属性可以在 Maven 构建过程中被引用。
  4. <altReleaseDeploymentRepository><altSnapshotDeploymentRepository> 属性

    • 这两个属性分别定义了发布版本和快照版本的部署仓库地址。格式为 <id>::default::<url>
    • <altReleaseDeploymentRepository>:指定了发布版本的部署仓库地址,这里使用的是 sl-releases 这个 ID,对应于 <servers> 配置中的一个服务器配置。
    • <altSnapshotDeploymentRepository>:指定了快照版本的部署仓库地址,这里使用的是 sl-snapshots 这个 ID,同样对应于 <servers> 配置中的一个服务器配置。
  5. <repositories> 标签

    • 这个标签用于定义项目依赖的远程仓库列表。
  6. 第一个 <repository> 配置

    • <id>sl-releases</id>:定义了仓库的唯一标识符(ID),与 <servers> 配置中的 ID 相对应。
    • <url>:指定了发布版本的远程仓库地址。
    • <releases>:指定了对于发布版本的配置,<enabled>true</enabled> 表示启用发布版本的下载。
    • <snapshots>:指定了对于快照版本的配置,<enabled>false</enabled> 表示禁用快照版本的下载。
  7. 第二个 <repository> 配置

    • <id>sl-snapshots</id>:定义了仓库的唯一标识符(ID),与 <servers> 配置中的 ID 相对应。
    • <url>:指定了快照版本的远程仓库地址。
    • <releases>:指定了对于发布版本的配置,<enabled>false</enabled> 表示禁用发布版本的下载。
    • <snapshots>:指定了对于快照版本的配置,<enabled>true</enabled> 表示启用快照版本的下载。

 

<?xml version="1.0" encoding="UTF-8"?>
<settings
        xmlns="http://maven.apache.org/SETTINGS/1.0.0"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0 http://maven.apache.org/xsd/settings-1.0.0.xsd">
    <!-- 本地仓库 -->
    <localRepository>F:\maven\repository</localRepository>
    <!-- 配置私服中deploy的账号 -->
    <servers>
        <server>
            <id>sl-releases</id>
            <username>deployment</username>
            <password>deployment123</password>
        </server>
        <server>
            <id>sl-snapshots</id>
            <username>deployment</username>
            <password>deployment123</password>
        </server>
    </servers>
    <!-- 使用阿里云maven镜像,排除私服资源库 -->
    <mirrors>
        <mirror>
            <id>mirror</id>
            <mirrorOf>central,jcenter,!sl-releases,!sl-snapshots</mirrorOf>
            <name>mirror</name>
            <url>https://maven.aliyun.com/nexus/content/groups/public</url>
        </mirror>
    </mirrors>
    <profiles>
        <profile>
            <id>sl</id>
            <!-- 配置项目deploy的地址 -->
            <properties>
                <altReleaseDeploymentRepository>
                    sl-releases::default::http://maven.sl-express.com/nexus/content/repositories/releases/
                </altReleaseDeploymentRepository>
                <altSnapshotDeploymentRepository>
                    sl-snapshots::default::http://maven.sl-express.com/nexus/content/repositories/snapshots/
                </altSnapshotDeploymentRepository>
            </properties>
            <!-- 配置项目下载依赖的私服地址 -->
            <repositories>
                <repository>
                    <id>sl-releases</id>
                    <url>http://maven.sl-express.com/nexus/content/repositories/releases/</url>
                    <releases>
                        <enabled>true</enabled>
                    </releases>
                    <snapshots>
                        <enabled>false</enabled>
                    </snapshots>
                </repository>
                <repository>
                    <id>sl-snapshots</id>
                    <url>http://maven.sl-express.com/nexus/content/repositories/snapshots/</url>
                    <releases>
                        <enabled>false</enabled>
                    </releases>
                    <snapshots>
                        <enabled>true</enabled>
                    </snapshots>
                </repository>
            </repositories>
        </profile>
    </profiles>
    <activeProfiles>
         <!-- 激活配置 -->
        <activeProfile>sl</activeProfile>
    </activeProfiles>
</settings>

配置的内容

http://maven.sl-express.com/nexus/content/repositories/releases

快照版和发布版的区别

在 Maven 中,快照版本(Snapshot)和发布版本(Release)是两种不同类型的版本,它们在版本控制和依赖管理中有着不同的用途和行为:

快照版本(Snapshot)

  • 开发阶段:快照版本通常用于开发阶段,它们表示代码还在积极开发中,可能会频繁变化。
  • 版本号:快照版本的版本号通常会包含时间戳或构建编号,例如 1.0-SNAPSHOT 或 1.0.1-SNAPSHOT
  • 更新频率:快照版本可能会非常频繁地更新,因为它们通常与持续集成(CI)流程相关联。
  • 不稳定性:由于快照版本是开发中的版本,它们可能不稳定,不保证向后兼容性。
  • 依赖更新:在 Maven 项目中,如果依赖了一个快照版本,Maven 会定期检查更新,并在发现新版本时自动更新依赖。

发布版本(Release)

  • 稳定阶段:发布版本用于表示已经稳定的代码,它们是经过测试和验证的,可以用于生产环境。
  • 版本号:发布版本的版本号不包含时间戳或构建编号,例如 1.0 或 1.0.1
  • 更新频率:发布版本的更新频率通常较低,只有在有新功能或修复时才会发布新版本。
  • 稳定性和兼容性:发布版本需要保证稳定性和向后兼容性,以确保依赖它们的项目能够正常运行。
  • 依赖锁定:在 Maven 项目中,如果依赖了一个发布版本,Maven 会锁定该版本的依赖,不会自动更新到新版本,除非显式地更改了版本号。

 导入发布版的父工程

    <parent>
        <groupId>com.sl-express</groupId>
        <artifactId>sl-express-parent</artifactId>
        <version>1.3</version>
    </parent>

快照版的父工程

 

理清楚授权规则

以上是授权路线图,我们需要跟着这幅图来理清楚这个项目的授权规则

一.首先浏览器发送/manager/**路径请求

一般根据请求路径的不同来转发到不同的微服务是由gateway网关来实现的,所以我们去gateway网关的application.yml文件中查看路径断言规则

spring:
  cloud:
    nacos:
      username: nacos
      password: nacos
      server-addr: 192.168.150.101:8848
      discovery:
        namespace: ecae68ba-7b43-4473-a980-4ddeb6157bdc
        ip: 192.168.150.1 #设置本地服务在nacos的地址与虚拟机ip的前三段相同,不然一部分微服务在本地跑,一部分在虚拟机跑
        #导致在nacos中的ip地址不同,以至于不同的微服务无法互相访问通
      config:
        namespace: ecae68ba-7b43-4473-a980-4ddeb6157bdc
    gateway:
      globalcors:
        cors-configurations:
          '[/**]':
            allowed-origin-patterns: "*"
            allowed-headers: "*"
            allow-credentials: true
            allowed-methods:
              - GET
              - POST
              - DELETE
              - PUT
              - OPTION
      discovery:
        locator:
          enabled: true #表明gateway开启服务注册和发现的功能,并且spring cloud gateway自动根据服务发现为每一个服务创建了一个router,这个router将以服务名开头的请求路径转发到对应的服务
      routes:
        - id: sl-express-ms-web-manager
          uri: lb://sl-express-ms-web-manager
          predicates:
            - Path=/manager/**
          filters:
            - StripPrefix=1
            - ManagerToken
            - AddRequestHeader=X-Request-From, sl-express-gateway

可以发现以/manager开头的路径会被负载均衡到lb://sl-express-ms-web-manager这个微服务中

不过在转发请求之前,还有三个过滤器

StripPrefix=1表示会跳过请求中的第一段在进行转发,即原来的路径会去掉/manager

AddRequestHeader=X-Request-From, sl-express-gateway表示添加请求头,表示请求的来源是gateway转发的

ManagerToken是自定义的过滤器,我们需要去查看这个过滤器的实现

   filters:
            - StripPrefix=1
            - ManagerToken
            - AddRequestHeader=X-Request-From, sl-express-gateway

gateway过滤器默认会省略后面的GatewayFilterFactory后缀,即应该为 ManagerTokenGatewayFilterFactory类

找到这个类

内容:

 该类继承了Gateway的AbstractGatewayFilterFactory<Object>类,表示这是一个过滤器

AuthFilter是自定义的接口,规定了检验token,和鉴权的方法

public interface AuthFilter {

    /**
     * 校验token
     *
     * @param token 请求中的token
     * @return token中携带的数据
     */
    AuthUserInfoDTO check(String token);

    /**
     * 鉴权
     *
     * @param token        请求中的token
     * @param authUserInfo token中携带的数据
     * @param path         当前请求的路径
     * @return 是否通过
     */
    Boolean auth(String token, AuthUserInfoDTO authUserInfo, String path);

}
/**
 * 后台管理员token拦截处理
 */
@Component
public class ManagerTokenGatewayFilterFactory extends AbstractGatewayFilterFactory<Object> implements AuthFilter {

    @Resource
    private MyConfig myConfig;
    @Resource
    private TokenCheckService tokenCheckService;
    //从配置文件中加载能访问后台管理的角色ids
    @Value("${role.manager}")
    private List<Long>managerRoleIds;

    @Override
    public GatewayFilter apply(Object config) {
        return new TokenGatewayFilter(this.myConfig, this);
    }

    @Override
    public AuthUserInfoDTO check(String token) {
        try {
            //校验token
            return tokenCheckService.parserToken(token);
        } catch (AuthSdkException e) {
            // 校验失败
        }
        return null;
    }

    @Override
    public Boolean auth(String token, AuthUserInfoDTO authUserInfoDTO, String path) {
        //获取AuthTemplate对象
        AuthTemplate authTemplate = AuthTemplateFactory.get(token);
        //查询该用户拥有的的角色id
        List<Long> roleIds = authTemplate.opsForRole().findRoleByUserId(authUserInfoDTO.getUserId()).getData();
        // 和配置的访问角色 取交集
        Collection<Long> intersection = CollUtil.intersection(roleIds, managerRoleIds);
        // 判断是否有交集即可判断出是否有权限
        return CollUtil.isNotEmpty(intersection);
    }
}

 第二步:构造了TokenGatewayFilter方法,并把myConfig对象和当前过滤器对象作为参数传入

我们来看一下MyConfig类是什么

可以看到与配置文件中的sl属性继续映射

@Data
@Component
@Configuration
@ConfigurationProperties(prefix = "sl")
public class MyConfig {

    private String[] noAuthPaths;

}

这个属性规定了不需要权限就可以直接访问的所有接口 

sl:
  noAuthPaths:
    - /courier/login/account
    - /courier/swagger-ui.html
    - /courier/webjars/
    - /courier/swagger-resources
    - /courier/v2/api-docs
    - /courier/doc.html
    - /customer/user/login
    - /customer/swagger-ui.html
    - /customer/webjars/
    - /customer/swagger-resources
    - /customer/v2/api-docs
    - /customer/doc.html
    - /driver/login/account
    - /driver/swagger-ui.html
    - /driver/webjars/
    - /driver/swagger-resources
    - /driver/v2/api-docs
    - /driver/doc.html
    - /manager/login
    - /manager/webjars/
    - /manager/swagger-resources
    - /manager/v2/api-docs
    - /manager/doc.html
    - /manager/captcha
@Slf4j
public class TokenGatewayFilter implements GatewayFilter, Ordered {

    private MyConfig myConfig;
    private AuthFilter authFilter;

    public TokenGatewayFilter(MyConfig myConfig, AuthFilter authFilter) {
        this.myConfig = myConfig;
        this.authFilter = authFilter;
    }
}

第三步:执行了filter方法并校验是否为放行path

如果是不需要授权的路径就直接放行,并从 Authorization请求头中获取token票据信息,如果票据信息为空,就禁止访问

票据信息是登录认证时,后端给前端发布的一个票据,包含了用户用户的基本信息和用户拥有的角色id,因为我们设置了获取验证码和登录是不需要验证鉴权的接口,所以可以直接访问然后获取该用户对应的票据信息

 - /manager/login
    - /manager/captcha

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        String path = exchange.getRequest().getPath().toString();
        if (StrUtil.startWithAny(path, myConfig.getNoAuthPaths())) {
            //无需校验,直接放行
            return chain.filter(exchange);
        }

        //获取header的参数
        String token = exchange.getRequest().getHeaders().getFirst("Authorization");
        if (StrUtil.isEmpty(token)) {
            //没有权限
            exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
            return exchange.getResponse().setComplete();
        }
}

第四步:执行AuthFilter的check方法,检验票据的合法性

 //校验token
        AuthUserInfoDTO authUserInfoDTO = null;
        try{ //捕获token校验异常
            authUserInfoDTO = this.authFilter.check(token);
        }catch (Exception e){
            log.error("权限校验失败,e:",e);
        }
        if (ObjectUtil.isEmpty(authUserInfoDTO)) {
            //token失效 或 伪造
            exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
            return exchange.getResponse().setComplete();
        }

会去调用AuthFilter的实现类ManagerTokenGatewayFilterFactory的check方法,因为已经把这个类的实例通过TokenGateWayFilter的构造方法传入,因此可以进行回调。

我们来看一下ManagerTokenGatewayFilterFactory的check方法

不合法就返回null

    @Override
    public AuthUserInfoDTO check(String token) {
        try {
            //校验token
            return tokenCheckService.parserToken(token);
        } catch (AuthSdkException e) {
            // 校验失败
        }
        return null;
    }

第五步:执行AuthFilter的auth方法,进行鉴权

 authUserInfoDTO是解析token时解析出来的用户的基本信息

        //鉴权
        Boolean result = false;
        try { //捕获鉴权异常
            result = this.authFilter.auth(token, authUserInfoDTO, path);
        }catch (Exception e){
            log.error("鉴权失败,e:",e);
        }
        if (!result) {
            //没有权限
            exchange.getResponse().setStatusCode(HttpStatus.BAD_REQUEST);
            return exchange.getResponse().setComplete();
        }

回调的ManagerTokenGatewayFilterFactory的auth方法

配置的可以访问的角色id是可以访问/manger开头接口的角色id,如果没有这些角色id就拒绝访问

这个配置文件在nacos配置中心中 

   //从配置文件中加载能访问后台管理的角色ids
    @Value("${role.manager}")
    private List<Long>managerRoleIds;
#角色id
role.manager = 986227712144197857,989278284569131905,996045142395786081,996045927523359809
    @Override
    public Boolean auth(String token, AuthUserInfoDTO authUserInfoDTO, String path) {
        //获取AuthTemplate对象
        AuthTemplate authTemplate = AuthTemplateFactory.get(token);
        //查询该用户拥有的的角色id
        List<Long> roleIds = authTemplate.opsForRole().findRoleByUserId(authUserInfoDTO.getUserId()).getData();
        // 和配置的访问角色 取交集
        Collection<Long> intersection = CollUtil.intersection(roleIds, managerRoleIds);
        // 判断是否有交集即可判断出是否有权限
        return CollUtil.isNotEmpty(intersection);
    }

所以,如果该用户可以访问就返回true,反之

第六步:放行

并添加了两个请求头,把用户的基本信息序列化成json格式,并把票据加上token请求头中 

    //增加参数
        exchange.getRequest().mutate().header("userInfo", JSONUtil.toJsonStr(authUserInfoDTO));
        exchange.getRequest().mutate().header("token", token);

        //校验通过放行
        return chain.filter(exchange);

完整的TokenGateWayFilter类

@Slf4j
public class TokenGatewayFilter implements GatewayFilter, Ordered {

    private MyConfig myConfig;
    private AuthFilter authFilter;

    public TokenGatewayFilter(MyConfig myConfig, AuthFilter authFilter) {
        this.myConfig = myConfig;
        this.authFilter = authFilter;
    }

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        String path = exchange.getRequest().getPath().toString();
        if (StrUtil.startWithAny(path, myConfig.getNoAuthPaths())) {
            //无需校验,直接放行
            return chain.filter(exchange);
        }

        //获取header的参数
        String token = exchange.getRequest().getHeaders().getFirst("Authorization");
        if (StrUtil.isEmpty(token)) {
            //没有权限
            exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
            return exchange.getResponse().setComplete();
        }

        //校验token
        AuthUserInfoDTO authUserInfoDTO = null;
        try{ //捕获token校验异常
            authUserInfoDTO = this.authFilter.check(token);
        }catch (Exception e){
            log.error("权限校验失败,e:",e);
        }
        if (ObjectUtil.isEmpty(authUserInfoDTO)) {
            //token失效 或 伪造
            exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
            return exchange.getResponse().setComplete();
        }

        //鉴权
        Boolean result = false;
        try { //捕获鉴权异常
            result = this.authFilter.auth(token, authUserInfoDTO, path);
        }catch (Exception e){
            log.error("鉴权失败,e:",e);
        }
        if (!result) {
            //没有权限
            exchange.getResponse().setStatusCode(HttpStatus.BAD_REQUEST);
            return exchange.getResponse().setComplete();
        }

        //增加参数
        exchange.getRequest().mutate().header("userInfo", JSONUtil.toJsonStr(authUserInfoDTO));
        exchange.getRequest().mutate().header("token", token);

        //校验通过放行
        return chain.filter(exchange);
    }

    @Override
    public int getOrder() {
        return Integer.MIN_VALUE;
    }
}

权限管家的api使用

依赖

    <dependency>
            <groupId>com.itheima.em.auth</groupId>
            <artifactId>itcast-auth-spring-boot-starter</artifactId>
        </dependency>
@SpringBootTest(properties = "spring.main.web-application-type = reactive")
public class AuthTemplateTest {

    @Resource
    private AuthTemplate authTemplate;
    @Resource
    private TokenCheckService tokenCheckService;
    @Autowired
    private AuthorityProperties authorityProperties;

    @Test
    public void testLogin() {
        //登录,生成token
        Result<LoginDTO> result = this.authTemplate.opsForLogin()
                .token("hhh", "123456");
        //得到token
        String token = result.getData().getToken().getToken();
        System.out.println("token为:" + token);
        //得到用户的消息
        UserDTO user = result.getData().getUser();
        System.out.println("user信息:" + user);

        //查询这个用户拥有的角色idd
        Result<List<Long>> resultRole = AuthTemplateFactory.get(token).opsForRole()
                .findRoleByUserId(user.getId());
        System.out.println(resultRole);
    }

    @Test
    public void checkToken() {
        //上面方法中生成的token
        String token = "eyJhbGciOiJSUzI1NiJ9.eyJzdWIiOiIxMzEyNDQ2OTcwNjUyMDAyODQ5IiwiYWNjb3VudCI6ImhoaCIsIm5hbWUiOiLkvZUiLCJvcmdpZCI6MTAyNTEwMzE3Njk0NjM5NTU4NSwic3RhdGlvbmlkIjoxMDI0NzA1NDg5NDM2NDk0NzIxLCJhZG1pbmlzdHJhdG9yIjpmYWxzZSwiZXhwIjoxNzMyOTk2NzI5fQ.lkOPgWXwOJ6OUuBiw4ctOyU7gl9sypxsYn2Sca4waHOFfxkQcVtSFzcKt-aieBS3Dn-vWfKx2YVQXkmggXOYIg";
        AuthUserInfoDTO authUserInfo = this.tokenCheckService.parserToken(token);
        System.out.println(authUserInfo);

        System.out.println(JSONUtil.toJsonStr(authUserInfo));
    }
}


http://www.kler.cn/a/419348.html

相关文章:

  • 数据结构入门(C语言复习)malloc开辟free释放
  • Vue 3 的双向绑定原理
  • FreeRTOS之vTaskStartScheduler实现分析
  • 【真正离线安装】Adobe Flash Player 32.0.0.156 插件离线安装包下载(无需联网安装)
  • Django Auth的基本使用
  • 汉字Unicode编码相互转换API集成指南
  • Redis中常见的延迟问题
  • unity中控制相机跟随物体移动
  • AI服务器从HBM到CXL的技术变革
  • 【UG\NX二次开发-Block UI】指定方位 VisibleManipulatorHandles 设置控制器手柄可见
  • 小车AI视觉交互--2.颜色跟随
  • 每日速记10道java面试题06
  • 七、Python —— 元组、集合和字典
  • windows部署PaddleSpeech详细教程
  • 解决Ubuntu下无法远程登录
  • Qt中QGraphics绘图类相关解释
  • Python PDF转JPG图片小工具
  • 深度学习-48-AI应用实战之基于face_recognition的人脸识别
  • 【AI日记】24.12.01 kaggle 比赛 Titanic-4
  • gitee:删除仓库
  • 【大模型】深度解析 NLP 模型5大评估指标及 应用案例:从 BLEU、ROUGE、PPL 到METEOR、BERTScore
  • Doris 2.1.7镜像制作
  • 【Figma】中文版安装
  • 【智能流体力学】RAG大模型方法:解决固体力学和流体动力学问题
  • 【优选算法篇】滑动窗口的艺术:如何动态调整子区间解决复杂问题(中篇)
  • 高德应用OceanBase云数据库的升级选型与迁移干货