1.添加sa-token依赖
<!-- Sa-Token 权限认证, 在线文档:http://sa-token.dev33.cn/ -->
<dependency>
<groupId>cn.dev33</groupId>
<artifactId>sa-token-spring-boot-starter</artifactId>
<version>1.29.0</version>
</dependency>
<!-- Sa-Token 整合 Redis (使用jackson序列化方式) -->
<dependency>
<groupId>cn.dev33</groupId>
<artifactId>sa-token-dao-redis-jackson</artifactId>
<version>1.29.0</version>
</dependency>
2.yml添加配置
# Sa-Token配置
sa-token:
# token名称 (同时也是cookie名称)
token-name: token
# token有效期,单位s 默认30天, -1代表永不过期
timeout: 20
# token临时有效期 (指定时间内无操作就视为token过期) 单位: 秒
activity-timeout: 20
# 是否允许同一账号并发登录 (为true时允许一起登录, 为false时新登录挤掉旧登录)
is-concurrent: false
# 在多人登录同一账号时,是否共用一个token (为true时所有登录共用一个token, 为false时每次登录新建一个token)
is-share: false
# token风格
token-style: uuid
# 是否输出操作日志
is-log: false
spring:
# redis配置
redis:
# Redis数据库索引(默认为0)
database: 1
# Redis服务器地址
host: 124.222.75.119
# Redis服务器连接端口
port: 6379
# Redis服务器连接密码(默认为空)
# password:
# 连接超时时间
timeout: 10s
lettuce:
pool:
# 连接池最大连接数
max-active: 200
# 连接池最大阻塞等待时间(使用负值表示没有限制)
max-wait: -1ms
# 连接池中的最大空闲连接
max-idle: 10
# 连接池中的最小空闲连接
min-idle: 0
启动类添加
/**
* 给redis配置序列化
* @param redisConnectionFactory
* @return
*/
@Bean
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
RedisTemplate<String, Object> template = new RedisTemplate<>();
template.setConnectionFactory(redisConnectionFactory);
//配置序列化凡是:key序列化为:String value序列化为JSON(默认使用Jackson)
template.setKeySerializer(RedisSerializer.string());
template.setValueSerializer(RedisSerializer.json());
template.setHashKeySerializer(RedisSerializer.string());
template.setHashValueSerializer(RedisSerializer.json());
return template;
}
3.登录获取token
@RequestMapping("/login")
public String login(String account,String pw){
if (!StringUtils.isEmpty(account) && !StringUtils.isEmpty(pw)) {
StpUtil.login("123", "PC");
SaTokenInfo tokenInfo = StpUtil.getTokenInfo();
return tokenInfo.getTokenValue();
}
return "";
}
4.添加拦截器
package com.demo.config;
import cn.dev33.satoken.interceptor.SaAnnotationInterceptor;
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 SaTokenConfigure implements WebMvcConfigurer {
// 注册Sa-Token的注解拦截器,打开注解式鉴权功能
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new SaAnnotationInterceptor()).addPathPatterns("/**");
}
}
使用
没有权限则会抛出异常,所以需要添加全局异常处理类
5.添加全局异常处理类
package com.demo.config;
import com.demo.result.Result;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.servlet.http.HttpServletRequest;
/**
* 全局异常处理
*
* @author ZhangJi
*/
@ControllerAdvice
public class DefaultExceptionHandler {
@ExceptionHandler(Exception.class)
@ResponseBody
public Object handleException(Exception e, HttpServletRequest request) {
//返回的结果集
Result result = new Result();
result.setCode(0);
result.setName(e.getMessage());
return result;
}
}
6. 自定义侦听器
package com.demo.listener;
import cn.dev33.satoken.listener.SaTokenListener;
import cn.dev33.satoken.stp.SaLoginModel;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
/**
* 自定义侦听器的实现
*/
@Component
public class MySaTokenListener implements SaTokenListener {
@Autowired
private RabbitTemplate rabbitTemplate;
/** 每次登录时触发 */
@Override
public void doLogin(String s, Object o, SaLoginModel saLoginModel) {
System.out.println("登录成功");
}
/** 每次注销时触发 */
@Override
public void doLogout(String loginType, Object loginId, String tokenValue) {
// ...
}
/** 每次被踢下线时触发 */
@Override
public void doKickout(String loginType, Object loginId, String tokenValue) {
// ...
System.out.println("您被踢下线了");
}
/** 每次被顶下线时触发 */
@Override
public void doReplaced(String loginType, Object loginId, String tokenValue) {
// ...
System.out.println("您被顶下线了");
//通过mq通知前端用户被顶下线
rabbitTemplate.convertAndSend(tokenValue,"10000");
}
/** 每次被封禁时触发 */
@Override
public void doDisable(String loginType, Object loginId, long disableTime) {
// ...
}
/** 每次被解封时触发 */
@Override
public void doUntieDisable(String loginType, Object loginId) {
// ...
}
/** 每次创建Session时触发 */
@Override
public void doCreateSession(String id) {
// ...
}
/** 每次注销Session时触发 */
@Override
public void doLogoutSession(String id) {
// ...
}
}
7.自定义权限验证接口
package com.demo.permissions;
import java.util.ArrayList;
import java.util.List;
import com.demo.mapper.PermissionsMapper;
import com.demo.mapper.RoleMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import cn.dev33.satoken.stp.StpInterface;
/**
* 自定义权限验证接口扩展
*/
@Component // 保证此类被SpringBoot扫描,完成Sa-Token的自定义权限验证扩展
public class StpInterfaceImpl implements StpInterface {
@Autowired
private PermissionsMapper permissionsMapper;
@Autowired
private RoleMapper roleMapper;
/**
* 返回一个账号所拥有的权限码集合
*/
@Override
public List<String> getPermissionList(Object loginId, String loginType) {
//查询用户所以权限
return permissionsMapper.getPermissionsInfo(loginId.toString());
}
/**
* 返回一个账号所拥有的角色标识集合 (权限与角色可分开校验)
*/
@Override
public List<String> getRoleList(Object loginId, String loginType) {
//查询用户所有角色
return roleMapper.getRole(loginId.toString());
}
}