开箱即用!看看人家的微服务权限解决方案,那叫一个优雅

return SaResult.error(e.getMessage());

});

}

}

  • 扩展下Sa-Token提供的StpInterface接口,用于获取用户的权限,我们在用户登录以后会把用户信息存到Session中去,权限信息也会在里面,所以权限码只要从Session中获取即可。

/**

  • 自定义权限验证接口扩展

*/

@Component

public class StpInterfaceImpl implements StpInterface {

@Override

public List getPermissionList(Object loginId, String loginType) {

// 返回此 loginId 拥有的权限码列表

UserDTO userDTO = (UserDTO) StpUtil.getSession().get(“userInfo”);

return userDTO.getPermissionList();

}

@Override

public List getRoleList(Object loginId, String loginType) {

// 返回此 loginId 拥有的角色码列表

return null;

}

}

micro-sa-token-auth

===================

接下来我们来搭建下认证服务,只要集成Sa-Token并实现登录接口即可,非常简单。

  • 首先在pom.xml中添加相关依赖,包括Sa-Token的SpringBoot依赖、整合Redis实现分布式Session的依赖以及我们的micro-sa-token-common依赖;

cn.dev33

sa-token-spring-boot-starter

1.24.0

cn.dev33

sa-token-dao-redis-jackson

1.24.0

org.apache.commons

commons-pool2

com.macro.cloud

micro-sa-token-common

1.0.0

  • 接下来修改配置文件application.yml,照抄之前网关的配置即可;

spring:

redis:

database: 0

port: 6379

host: localhost

password:

Sa-Token配置

sa-token:

token名称 (同时也是cookie名称)

token-name: Authorization

token有效期,单位秒,-1代表永不过期

timeout: 2592000

token临时有效期 (指定时间内无操作就视为token过期),单位秒

activity-timeout: -1

是否允许同一账号并发登录 (为false时新登录挤掉旧登录)

is-concurrent: true

在多人登录同一账号时,是否共用一个token (为false时每次登录新建一个token)

is-share: false

token风格

token-style: uuid

是否输出操作日志

is-log: false

是否从cookie中读取token

is-read-cookie: false

是否从head中读取token

is-read-head: true

  • 在UserController中定义好登录接口,登录成功后返回Token,具体实现在UserServiceImpl类中;

/**

  • 自定义Oauth2获取令牌接口

  • Created by macro on 2020/7/17.

*/

@RestController

@RequestMapping(“/user”)

public class UserController {

@Autowired

private UserServiceImpl userService;

@RequestMapping(value = “/login”, method = RequestMethod.POST)

public CommonResult login(@RequestParam String username, @RequestParam String password) {

SaTokenInfo saTokenInfo = userService.login(username, password);

if (saTokenInfo == null) {

return CommonResult.validateFailed(“用户名或密码错误”);

}

Map<String, String> tokenMap = new HashMap<>();

tokenMap.put(“token”, saTokenInfo.getTokenValue());

tokenMap.put(“tokenHead”, saTokenInfo.getTokenName());

return CommonResult.success(tokenMap);

}

}

  • 在UserServiceImpl中添加登录的具体逻辑,首先验证密码,密码校验成功后,通知下Sa-Token登录的用户ID,然后把用户信息直接存储到Session中去;

/**

  • 用户管理业务类

  • Created by macro on 2020/6/19.

*/

@Service

public class UserServiceImpl{

private List userList;

public SaTokenInfo login(String username, String password) {

SaTokenInfo saTokenInfo = null;

UserDTO userDTO = loadUserByUsername(username);

if (userDTO == null) {

return null;

}

if (!SaSecureUtil.md5(password).equals(userDTO.getPassword())) {

return null;

}

// 密码校验成功后登录,一行代码实现登录

StpUtil.login(userDTO.getId());

// 将用户信息存储到Session中

StpUtil.getSession().set(“userInfo”,userDTO);

// 获取当前登录用户Token信息

saTokenInfo = StpUtil.getTokenInfo();

return saTokenInfo;

}

}

  • 这里有一点需要提醒下,Sa-Token的Session并不是我们平时理解的HttpSession,而是它自己实现的类似Session的机制。

micro-sa-token-api

==================

接下来我们来搭建一个受保护的API服务,实现获取登录用户信息的接口和需要特殊权限才能访问的测试接口。

  • 首先在pom.xml中添加相关依赖,和上面的micro-sa-token-auth一样;

cn.dev33

sa-token-spring-boot-starter

1.24.0

cn.dev33

sa-token-dao-redis-jackson

1.24.0

org.apache.commons

commons-pool2

com.macro.cloud

micro-sa-token-common

1.0.0

  • 接下来修改配置文件application.yml,照抄之前网关的配置即可;

spring:

redis:

database: 0

port: 6379

host: localhost

password:

Sa-Token配置

sa-token:

token名称 (同时也是cookie名称)

token-name: Authorization

token有效期,单位秒,-1代表永不过期

timeout: 2592000

token临时有效期 (指定时间内无操作就视为token过期),单位秒

activity-timeout: -1

是否允许同一账号并发登录 (为false时新登录挤掉旧登录)

is-concurrent: true

在多人登录同一账号时,是否共用一个token (为false时每次登录新建一个token)

is-share: false

token风格

token-style: uuid

是否输出操作日志

is-log: false

是否从cookie中读取token

is-read-cookie: false

是否从head中读取token

is-read-head: true

  • 添加获取用户信息的接口,由于使用了Redis实现分布式Session,直接从Session中获取即可,是不是非常简单!

/**

  • 获取登录用户信息接口

  • Created by macro on 2020/6/19.

*/

@RestController

@RequestMapping(“/user”)

public class UserController{

@GetMapping(“/info”)

public CommonResult userInfo() {

UserDTO userDTO = (UserDTO) StpUtil.getSession().get(“userInfo”);

return CommonResult.success(userDTO);

}

}

  • 添加需要api:test:hello权限访问的测试接口,预置的admin用户拥有该权限,而macro用户是没有的。

/**

  • 测试接口

  • Created by macro on 2020/6/19.

*/

@RestController

@RequestMapping(“/test”)

public class TestController {

@GetMapping(“/hello”)

public CommonResult hello() {

return CommonResult.success(“Hello World.”);

}

}

功能演示

====

三个服务搭建完成后,我们用Postman来演示下微服务的认证授权功能。

  • 首先启动Nacos和Redis服务,然后再启动micro-sa-token-gateway、micro-sa-token-auth和micro-sa-token-api服务,启动顺序无所谓;

开箱即用!看看人家的微服务权限解决方案,那叫一个优雅

  • 直接通过网关访问登录接口获取Token,访问地址:http://localhost:9201/auth/user/login

开箱即用!看看人家的微服务权限解决方案,那叫一个优雅

  • 通过网关访问API服务,不带Token调用获取用户信息的接口,无法正常访问,访问地址:http://localhost:9201/api/user/info

开箱即用!看看人家的微服务权限解决方案,那叫一个优雅

  • 通过网关访问API服务,带Token调用获取用户信息的接口,可以正常访问;

开箱即用!看看人家的微服务权限解决方案,那叫一个优雅

  • 通过网关访问API服务,使用macro用户访问需api:test:hello权限的测试接口,无法正常访问,访问地址:http://localhost:9201/api/test/hello

开箱即用!看看人家的微服务权限解决方案,那叫一个优雅

  • 登录切换为admin用户,该用户具有api:test:hello权限;

开箱即用!看看人家的微服务权限解决方案,那叫一个优雅

最后

ActiveMQ消息中间件面试专题

  • 什么是ActiveMQ?
  • ActiveMQ服务器宕机怎么办?
  • 丢消息怎么办?
  • 持久化消息非常慢怎么办?
  • 消息的不均匀消费怎么办?
  • 死信队列怎么办?
  • ActiveMQ中的消息重发时间间隔和重发次数吗?

ActiveMQ消息中间件面试专题解析拓展:

BAT面试文档:ActiveMQ+redis+Spring+高并发多线程+JVM


redis面试专题及答案

  • 支持一致性哈希的客户端有哪些?
  • Redis与其他key-value存储有什么不同?
  • Redis的内存占用情况怎么样?
  • 都有哪些办法可以降低Redis的内存使用情况呢?
  • 查看Redis使用情况及状态信息用什么命令?
  • Redis的内存用完了会发生什么?
  • Redis是单线程的,如何提高多核CPU的利用率?

BAT面试文档:ActiveMQ+redis+Spring+高并发多线程+JVM


Spring面试专题及答案

  • 谈谈你对 Spring 的理解
  • Spring 有哪些优点?
  • Spring 中的设计模式
  • 怎样开启注解装配以及常用注解
  • 简单介绍下 Spring bean 的生命周期

Spring面试答案解析拓展

BAT面试文档:ActiveMQ+redis+Spring+高并发多线程+JVM


高并发多线程面试专题

  • 现在有线程 T1、T2 和 T3。你如何确保 T2 线程在 T1 之后执行,并且 T3 线程在 T2 之后执行?
  • Java 中新的 Lock 接口相对于同步代码块(synchronized block)有什么优势?如果让你实现一个高性能缓存,支持并发读取和单一写入,你如何保证数据完整性。
  • Java 中 wait 和 sleep 方法有什么区别?
  • 如何在 Java 中实现一个阻塞队列?
  • 如何在 Java 中编写代码解决生产者消费者问题?
  • 写一段死锁代码。你在 Java 中如何解决死锁?

高并发多线程面试解析与拓展

BAT面试文档:ActiveMQ+redis+Spring+高并发多线程+JVM


jvm面试专题与解析

  • JVM 由哪些部分组成?
  • JVM 内存划分?
  • Java 的内存模型?
  • 引用的分类?
  • GC什么时候开始?

JVM面试专题解析与拓展!

BAT面试文档:ActiveMQ+redis+Spring+高并发多线程+JVM

ng 中的设计模式

  • 怎样开启注解装配以及常用注解
  • 简单介绍下 Spring bean 的生命周期

Spring面试答案解析拓展

[外链图片转存中…(img-JZMKcyb9-1721187911640)]


高并发多线程面试专题

  • 现在有线程 T1、T2 和 T3。你如何确保 T2 线程在 T1 之后执行,并且 T3 线程在 T2 之后执行?
  • Java 中新的 Lock 接口相对于同步代码块(synchronized block)有什么优势?如果让你实现一个高性能缓存,支持并发读取和单一写入,你如何保证数据完整性。
  • Java 中 wait 和 sleep 方法有什么区别?
  • 如何在 Java 中实现一个阻塞队列?
  • 如何在 Java 中编写代码解决生产者消费者问题?
  • 写一段死锁代码。你在 Java 中如何解决死锁?

高并发多线程面试解析与拓展

[外链图片转存中…(img-oS2ZToUt-1721187911641)]


jvm面试专题与解析

  • JVM 由哪些部分组成?
  • JVM 内存划分?
  • Java 的内存模型?
  • 引用的分类?
  • GC什么时候开始?

JVM面试专题解析与拓展!

[外链图片转存中…(img-3dpezkSL-1721187911642)]

  • 14
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值