JAVA springboot中使用Sa-Token 推荐一个意外发现的优雅的token工具类,(还不止token,还有其他意想不到的惊喜)拿来就用。登录成功才可以访问其他接口,未登录或登录失败提示
·
sa-token官方文档
https://sa-token.cc/doc.html#/

java 配置
https://sa-token.cc/doc.html#/start/example
登录成功才可以访问接口,未登录或登录失败提示效果:

———————————— 进入主题 ————————————
一、pom依赖
<dependency>
<groupId>cn.dev33</groupId>
<artifactId>sa-token-spring-boot-starter</artifactId>
<version>1.44.0</version>
</dependency>
二、配置文件properties
# token 名称(同时也是 cookie 名称)
sa-token.token-name=token
# token 有效期(单位:秒) 默认30天,-1 代表永久有效
sa-token.timeout=2592000
# token 最低活跃频率(单位:秒),如果 token 超过此时间没有访问系统就会被冻结,默认-1 代表不限制,永不冻结
sa-token.active-timeout=-1
# 是否允许同一账号多地同时登录 (为 true 时允许一起登录, 为 false 时新登录挤掉旧登录)
sa-token.is-concurrent=true
# 在多人登录同一账号时,是否共用一个 token (为 true 时所有登录共用一个 token, 为 false 时每次登录新建一个 token)
sa-token.is-share=false
# token 风格(默认可取值:uuid、simple-uuid、random-32、random-64、random-128、tik)
sa-token.token-style=uuid
# 是否输出操作日志
sa-token.is-log=true
三、登录接口【重点】
启动类
public class MainApplication {
public static void main(String[] args) {
SpringApplication.run(MainApplication.class, args);
//自己的启动类
System.out.println("启动成功,Sa-Token 配置如下:" + SaManager.getConfig());
}
}
controller
/**
* 账号密码登录
*
* @param user
* @return
* @throws Exception
*/
@PostMapping("/login")
public Users login(@RequestBody UsersVo user) throws Exception {
return loginService.login(user);
}
service
/**
* 账号密码登录
*
* @param user
* @return
* @throws Exception
*/
Users login(UsersVo user) throws Exception;
serviceImpl
/**
* 账号密码登录
*
* @param user
* @return
* @throws Exception
*/
@Override
public Users login(UsersVo user) throws Exception {
// 查询用户信息
Users checkUser = findUserByUsername(user.getUsername());
if (checkUser == null) {
throw new GracefulResponseException("登录失败!");
}
//校验密码
if (!user.getPwd().equals(user.getPwd())) {
throw new GracefulResponseException("登录失败!");
}
// 第1步,先登录上
StpUtil.login(checkUser.getId());
// 第2步,获取 Token 相关参数
SaTokenInfo tokenInfo = StpUtil.getTokenInfo();
// 第3步,返回给前端
checkUser.setToken(tokenInfo.getTokenValue());
return checkUser;
}
四、拦截器+跨域 工具类【访问每个就扣都会验证一次token,不需要每个接口单独加】【重点】
import cn.dev33.satoken.stp.StpUtil;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* Token拦截器 - 验证用户登录状态
*/
@Component
public class TokenInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
// 放行 OPTIONS 预检请求
if ("OPTIONS".equalsIgnoreCase(request.getMethod())) {
return true;
}
// 检查用户是否登录
if (!StpUtil.isLogin()) {
// 未登录,返回错误信息
response.setStatus(201);
response.setContentType("application/json;charset=utf-8");
response.getWriter().write("{\"code\": \"201\", \"msg\": \"未登录,无法访问此接口\"}");
return false;
}
// 已登录,放行请求
return true;
}
}
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
/**
* 跨域配置和拦截器配置
*/
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
static final String[] ORIGINS = new String[]{"GET", "POST", "PUT", "DELETE", "OPTIONS"};
@Autowired
private TokenInterceptor tokenInterceptor;
@Override
public void addCorsMappings(CorsRegistry registry) {
// 所有的当前站点的请求地址,都支持跨域访问
registry.addMapping("/**")
// 所有的外部域都可跨域访问
.allowedOriginPatterns("*")
// 是否支持跨域预约凭证
.allowCredentials(true)
// 当前站点支持的跨域请求类型是什么
.allowedMethods(ORIGINS)
// 超时时长设置为1小时 时间单位是秒
.maxAge(3600);
}
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(tokenInterceptor)
// 拦截所有接口
.addPathPatterns("/**")
// 排除登录接口、文档接口等不需要拦截的路径
.excludePathPatterns(
"/自己的项目api/自己的登录login"
);
}
}
更多推荐


所有评论(0)