当前位置:   article > 正文

【Sa-Token|2】Sa-Token在微服务中的使用_satoken 分布式 微服务

satoken 分布式 微服务

微服务架构中,使用 Sa-Token 进行分布式认证和权限管理需要考虑到各个服务之间的通信和 Token
的共享。以下是一个详细的教程,介绍如何在微服务中使用 Sa-Token

1. 微服务架构介绍

假设有以下几个微服务:

  • AuthService: 负责用户认证和 Token 生成。
  • UserService: 负责用户信息管理。
  • OrderService: 负责订单管理。

2. 引入依赖

在每个微服务中引入 Sa-Token 的依赖。以 Maven 项目为例,可以在每个服务的 pom.xml 文件中添加以下依赖:

<dependency>
    <groupId>cn.dev33</groupId>
    <artifactId>sa-token-spring-boot-starter</artifactId>
    <version>1.31.0</version>
</dependency>
  • 1
  • 2
  • 3
  • 4
  • 5

3. 配置 Sa-Token

在每个微服务中配置 Sa-Token。在 application.ymlapplication.properties 文件中添加配置。例如:

sa-token:
  token-name: satoken
  timeout: 86400
  activity-timeout: -1
  is-read-cookie: true
  is-log: false
  is-splicing: false
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

4. AuthService 实现

AuthService 负责用户的认证和 Token 生成。

AuthController
import cn.dev33.satoken.stp.StpUtil;
import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping("/auth")
public class AuthController {

    @PostMapping("/login")
    public String login(@RequestParam String username, @RequestParam String password) {
        // 假设这是从数据库中查找的用户信息
        if ("admin".equals(username) && "123456".equals(password)) {
            StpUtil.login(10001);
            return "登录成功,Token: " + StpUtil.getTokenValue();
        }
        return "登录失败";
    }

    @PostMapping("/logout")
    public String logout() {
        StpUtil.logout();
        return "注销成功";
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23

5. 其他微服务的配置

其他微服务(如 UserService 和 OrderService)需要在请求中携带 Token 并进行验证。

配置全局拦截器

在每个微服务中配置全局拦截器以验证 Token。

import cn.dev33.satoken.interceptor.SaInterceptor;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class SaTokenConfig implements WebMvcConfigurer {

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new SaInterceptor()).addPathPatterns("/**")
                .excludePathPatterns("/auth/login", "/auth/logout");
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
UserController 示例
import cn.dev33.satoken.stp.StpUtil;
import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping("/user")
public class UserController {

    @GetMapping("/info")
    public String getUserInfo() {
        StpUtil.checkLogin(); // 检查是否登录
        int userId = StpUtil.getLoginIdAsInt();
        // 根据 userId 获取用户信息(省略具体逻辑)
        return "用户信息";
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
OrderController 示例
import cn.dev33.satoken.stp.StpUtil;
import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping("/order")
public class OrderController {

    @GetMapping("/list")
    public String getOrderList() {
        StpUtil.checkLogin(); // 检查是否登录
        int userId = StpUtil.getLoginIdAsInt();
        // 根据 userId 获取订单列表(省略具体逻辑)
        return "订单列表";
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

6. 微服务之间的调用

在微服务之间调用时,需要在请求头中携带 Token。可以使用 Feign Client 进行服务间调用。

Feign 配置

添加 Feign Client 依赖:

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
  • 1
  • 2
  • 3
  • 4
创建 Feign Client

例如,在 UserService 中调用 OrderService:

import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestHeader;

@FeignClient(name = "order-service")
public interface OrderServiceClient {

    @GetMapping("/order/list")
    String getOrderList(@RequestHeader("satoken") String token);
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
在控制器中使用 Feign Client
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping("/user")
public class UserController {

    @Autowired
    private OrderServiceClient orderServiceClient;

    @GetMapping("/orders")
    public String getUserOrders() {
        StpUtil.checkLogin(); // 检查是否登录
        String token = StpUtil.getTokenValue();
        return orderServiceClient.getOrderList(token);
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

7. 集成 Redis 实现分布式会话

为了在分布式系统中共享 Token,可以使用 Redis 存储会话信息。

引入 Redis 依赖

pom.xml 文件中添加 Redis 依赖:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
  • 1
  • 2
  • 3
  • 4
配置 Redis

application.yml 中配置 Redis 连接信息:

spring:
  redis:
    host: localhost
    port: 6379
  • 1
  • 2
  • 3
  • 4
启用 Redis 存储

在 Sa-Token 配置类中启用 Redis 存储:

import cn.dev33.satoken.dao.SaTokenDaoRedis;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;

@Configuration
public class SaTokenConfig {

    @Bean
    public SaTokenDaoRedis saTokenDaoRedis(RedisConnectionFactory connectionFactory) {
        return new SaTokenDaoRedis(connectionFactory);
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

8. 完整示例

以下是一个包含登录、注销、权限验证和微服务间调用的完整示例:

AuthService
@RestController
@RequestMapping("/auth")
public class AuthController {

    @PostMapping("/login")
    public String login(@RequestParam String username, @RequestParam String password) {
        if ("admin".equals(username) && "123456".equals(password)) {
            StpUtil.login(10001);
            return "登录成功,Token: " + StpUtil.getTokenValue();
        }
        return "登录失败";
    }

    @PostMapping("/logout")
    public String logout() {
        StpUtil.logout();
        return "注销成功";
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
UserService
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping("/user")
public class UserController {

    @Autowired
    private OrderServiceClient orderServiceClient;

    @GetMapping("/info")
    public String getUserInfo() {
        StpUtil.checkLogin();
        return "用户信息";
    }

    @GetMapping("/orders")
    public String getUserOrders() {
        StpUtil.checkLogin();
        String token = StpUtil.getTokenValue();
        return orderServiceClient.getOrderList(token);
    }
}

@FeignClient(name = "order-service")
public interface OrderServiceClient {

    @GetMapping("/order/list")
    String getOrderList(@RequestHeader("satoken") String token);
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
OrderService
import cn.dev33.satoken.stp.StpUtil;
import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping("/order")
public class OrderController {

    @GetMapping("/list")
    public String getOrderList(@RequestHeader("satoken") String token) {
        StpUtil.checkLogin(); // 检查是否登录
        return "订单列表";
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

通过以上步骤,你已经完成了在微服务架构中使用 Sa-Token 进行分布式认证和权限管理的基本配置。你可以根据具体需求进行扩展和调整。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/一键难忘520/article/detail/765780
推荐阅读
  

闽ICP备14008679号