mirror of
https://gitee.com/dromara/sa-token.git
synced 2025-06-28 13:34:18 +08:00
Web-Socket 鉴权示例
This commit is contained in:
parent
fbc139b430
commit
40a5cdc6dc
12
sa-token-demo/sa-token-demo-websocket-spring/.gitignore
vendored
Normal file
12
sa-token-demo/sa-token-demo-websocket-spring/.gitignore
vendored
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
target/
|
||||||
|
|
||||||
|
node_modules/
|
||||||
|
bin/
|
||||||
|
.settings/
|
||||||
|
unpackage/
|
||||||
|
.classpath
|
||||||
|
.project
|
||||||
|
|
||||||
|
.idea/
|
||||||
|
|
||||||
|
.factorypath
|
69
sa-token-demo/sa-token-demo-websocket-spring/pom.xml
Normal file
69
sa-token-demo/sa-token-demo-websocket-spring/pom.xml
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
<groupId>cn.dev33</groupId>
|
||||||
|
<artifactId>sa-token-demo-websocket-spring</artifactId>
|
||||||
|
<version>0.0.1-SNAPSHOT</version>
|
||||||
|
|
||||||
|
<!-- SpringBoot -->
|
||||||
|
<parent>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-parent</artifactId>
|
||||||
|
<version>2.0.0.RELEASE</version>
|
||||||
|
<!-- <version>1.5.9.RELEASE</version> -->
|
||||||
|
<relativePath/>
|
||||||
|
</parent>
|
||||||
|
|
||||||
|
<!-- 定义sa-token版本号 -->
|
||||||
|
<properties>
|
||||||
|
<sa-token-version>1.29.0</sa-token-version>
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
|
||||||
|
<!-- SpringBoot依赖 -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-web</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-aop</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- WebScoket 依赖 -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-websocket</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- Sa-Token 权限认证, 在线文档:http://sa-token.dev33.cn/ -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>cn.dev33</groupId>
|
||||||
|
<artifactId>sa-token-spring-boot-starter</artifactId>
|
||||||
|
<version>${sa-token-version}</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- Sa-Token整合 Redis (使用jackson序列化方式) -->
|
||||||
|
<!-- <dependency>
|
||||||
|
<groupId>cn.dev33</groupId>
|
||||||
|
<artifactId>sa-token-dao-redis-jackson</artifactId>
|
||||||
|
<version>${sa-token-version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.commons</groupId>
|
||||||
|
<artifactId>commons-pool2</artifactId>
|
||||||
|
</dependency> -->
|
||||||
|
|
||||||
|
<!-- @ConfigurationProperties -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-configuration-processor</artifactId>
|
||||||
|
<optional>true</optional>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
|
||||||
|
</project>
|
@ -0,0 +1,32 @@
|
|||||||
|
package com.pj;
|
||||||
|
|
||||||
|
import org.springframework.boot.SpringApplication;
|
||||||
|
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||||
|
|
||||||
|
import cn.dev33.satoken.SaManager;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sa-Token 整合 WebSocket 鉴权示例
|
||||||
|
* @author kong
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@SpringBootApplication
|
||||||
|
public class SaTokenWebSocketSpringApplication {
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 1、访问登录接口,拿到会话Token:
|
||||||
|
* http://localhost:8081/acc/doLogin?name=zhang&pwd=123456
|
||||||
|
*
|
||||||
|
* 2、找一个WebSocket在线测试页面进行连接,
|
||||||
|
* 例如:
|
||||||
|
* https://www.bejson.com/httputil/websocket/
|
||||||
|
* 然后连接地址:
|
||||||
|
* ws://localhost:8081/ws-connect?satoken=2e6db38f-1e78-40bc-aa8f-e8f1f77fbef5
|
||||||
|
*/
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
SpringApplication.run(SaTokenWebSocketSpringApplication.class, args);
|
||||||
|
System.out.println("\n启动成功:Sa-Token配置如下:" + SaManager.getConfig());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,48 @@
|
|||||||
|
package com.pj.test;
|
||||||
|
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
import cn.dev33.satoken.stp.StpUtil;
|
||||||
|
import cn.dev33.satoken.util.SaResult;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 登录测试
|
||||||
|
* @author kong
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/acc/")
|
||||||
|
public class LoginController {
|
||||||
|
|
||||||
|
// 测试登录 ---- http://localhost:8081/acc/doLogin?name=zhang&pwd=123456
|
||||||
|
@RequestMapping("doLogin")
|
||||||
|
public SaResult doLogin(String name, String pwd) {
|
||||||
|
// 此处仅作模拟示例,真实项目需要从数据库中查询数据进行比对
|
||||||
|
if("zhang".equals(name) && "123456".equals(pwd)) {
|
||||||
|
StpUtil.login(10001);
|
||||||
|
return SaResult.ok("登录成功").set("token", StpUtil.getTokenValue());
|
||||||
|
}
|
||||||
|
return SaResult.error("登录失败");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 查询登录状态 ---- http://localhost:8081/acc/isLogin
|
||||||
|
@RequestMapping("isLogin")
|
||||||
|
public SaResult isLogin() {
|
||||||
|
return SaResult.ok("是否登录:" + StpUtil.isLogin());
|
||||||
|
}
|
||||||
|
|
||||||
|
// 查询 Token 信息 ---- http://localhost:8081/acc/tokenInfo
|
||||||
|
@RequestMapping("tokenInfo")
|
||||||
|
public SaResult tokenInfo() {
|
||||||
|
return SaResult.data(StpUtil.getTokenInfo());
|
||||||
|
}
|
||||||
|
|
||||||
|
// 测试注销 ---- http://localhost:8081/acc/logout
|
||||||
|
@RequestMapping("logout")
|
||||||
|
public SaResult logout() {
|
||||||
|
StpUtil.logout();
|
||||||
|
return SaResult.ok();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,83 @@
|
|||||||
|
package com.pj.ws;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
|
import org.springframework.web.socket.CloseStatus;
|
||||||
|
import org.springframework.web.socket.TextMessage;
|
||||||
|
import org.springframework.web.socket.WebSocketSession;
|
||||||
|
import org.springframework.web.socket.handler.TextWebSocketHandler;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 处理 WebSocket 连接
|
||||||
|
*
|
||||||
|
* @author kong
|
||||||
|
* @date: 2022-2-11
|
||||||
|
*/
|
||||||
|
public class MyWebSocketHandler extends TextWebSocketHandler {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 固定前缀
|
||||||
|
*/
|
||||||
|
private static final String USER_ID = "user_id_";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 存放Session集合,方便推送消息
|
||||||
|
*/
|
||||||
|
private static ConcurrentHashMap<String, WebSocketSession> webSocketSessionMaps = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
|
// 监听:连接开启
|
||||||
|
@Override
|
||||||
|
public void afterConnectionEstablished(WebSocketSession session) throws Exception {
|
||||||
|
|
||||||
|
// put到集合,方便后续操作
|
||||||
|
String userId = session.getAttributes().get("userId").toString();
|
||||||
|
webSocketSessionMaps.put(USER_ID + userId, session);
|
||||||
|
|
||||||
|
|
||||||
|
// 给个提示
|
||||||
|
String tips = "Web-Socket 连接成功,sid=" + session.getId() + ",userId=" + userId;
|
||||||
|
System.out.println(tips);
|
||||||
|
sendMessage(session, tips);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 监听:连接关闭
|
||||||
|
@Override
|
||||||
|
public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
|
||||||
|
// 从集合移除
|
||||||
|
String userId = session.getAttributes().get("userId").toString();
|
||||||
|
webSocketSessionMaps.remove(USER_ID + userId);
|
||||||
|
|
||||||
|
// 给个提示
|
||||||
|
String tips = "Web-Socket 连接关闭,sid=" + session.getId() + ",userId=" + userId;
|
||||||
|
System.out.println(tips);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 收到消息
|
||||||
|
@Override
|
||||||
|
public void handleTextMessage(WebSocketSession session, TextMessage message) throws IOException {
|
||||||
|
System.out.println("sid为:" + session.getId() + ",发来:" + message);
|
||||||
|
}
|
||||||
|
|
||||||
|
// -----------
|
||||||
|
|
||||||
|
// 向指定客户端推送消息
|
||||||
|
public static void sendMessage(WebSocketSession session, String message) {
|
||||||
|
try {
|
||||||
|
System.out.println("向sid为:" + session.getId() + ",发送:" + message);
|
||||||
|
session.sendMessage(new TextMessage(message));
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 向指定用户推送消息
|
||||||
|
public static void sendMessage(long userId, String message) {
|
||||||
|
WebSocketSession session = webSocketSessionMaps.get(USER_ID + userId);
|
||||||
|
if(session != null) {
|
||||||
|
sendMessage(session, message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,30 @@
|
|||||||
|
package com.pj.ws;
|
||||||
|
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.web.socket.config.annotation.EnableWebSocket;
|
||||||
|
import org.springframework.web.socket.config.annotation.WebSocketConfigurer;
|
||||||
|
import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* WebSocket 相关配置
|
||||||
|
*
|
||||||
|
* @author kong
|
||||||
|
* @date: 2022-2-11
|
||||||
|
*/
|
||||||
|
@Configuration
|
||||||
|
@EnableWebSocket
|
||||||
|
public class WebSocketConfig implements WebSocketConfigurer {
|
||||||
|
|
||||||
|
// 注册 WebSocket 处理器
|
||||||
|
@Override
|
||||||
|
public void registerWebSocketHandlers(WebSocketHandlerRegistry webSocketHandlerRegistry) {
|
||||||
|
webSocketHandlerRegistry
|
||||||
|
// WebSocket 连接处理器
|
||||||
|
.addHandler(new MyWebSocketHandler(), "/ws-connect")
|
||||||
|
// WebSocket 拦截器
|
||||||
|
.addInterceptors(new WebSocketInterceptor())
|
||||||
|
// 允许跨域
|
||||||
|
.setAllowedOrigins("*");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,45 @@
|
|||||||
|
package com.pj.ws;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.springframework.http.server.ServerHttpRequest;
|
||||||
|
import org.springframework.http.server.ServerHttpResponse;
|
||||||
|
import org.springframework.web.socket.WebSocketHandler;
|
||||||
|
import org.springframework.web.socket.server.HandshakeInterceptor;
|
||||||
|
|
||||||
|
import cn.dev33.satoken.stp.StpUtil;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* WebSocket 握手的前置拦截器
|
||||||
|
*
|
||||||
|
* @author kong
|
||||||
|
* @date: 2022-2-11
|
||||||
|
*/
|
||||||
|
public class WebSocketInterceptor implements HandshakeInterceptor {
|
||||||
|
|
||||||
|
// 握手之前触发 (return true 才会握手成功 )
|
||||||
|
@Override
|
||||||
|
public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler handler,
|
||||||
|
Map<String, Object> attr) {
|
||||||
|
|
||||||
|
System.out.println("---- 握手之前触发 " + StpUtil.getTokenValue());
|
||||||
|
|
||||||
|
// 未登录情况下拒绝握手
|
||||||
|
if(StpUtil.isLogin() == false) {
|
||||||
|
System.out.println("---- 未授权客户端,连接失败");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 标记 userId,握手成功
|
||||||
|
attr.put("userId", StpUtil.getLoginIdAsLong());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 握手之后触发
|
||||||
|
@Override
|
||||||
|
public void afterHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler,
|
||||||
|
Exception exception) {
|
||||||
|
System.out.println("---- 握手之后触发 ");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,49 @@
|
|||||||
|
# 端口
|
||||||
|
server:
|
||||||
|
port: 8081
|
||||||
|
|
||||||
|
# sa-token配置
|
||||||
|
sa-token:
|
||||||
|
# token名称 (同时也是cookie名称)
|
||||||
|
token-name: satoken
|
||||||
|
# token有效期,单位s 默认30天, -1代表永不过期
|
||||||
|
timeout: 2592000
|
||||||
|
# token临时有效期 (指定时间内无操作就视为token过期) 单位: 秒
|
||||||
|
activity-timeout: -1
|
||||||
|
# 是否允许同一账号并发登录 (为true时允许一起登录, 为false时新登录挤掉旧登录)
|
||||||
|
is-concurrent: true
|
||||||
|
# 在多人登录同一账号时,是否共用一个token (为true时所有登录共用一个token, 为false时每次登录新建一个token)
|
||||||
|
is-share: true
|
||||||
|
# token风格
|
||||||
|
token-style: uuid
|
||||||
|
# 是否输出操作日志
|
||||||
|
is-log: false
|
||||||
|
|
||||||
|
spring:
|
||||||
|
# redis配置
|
||||||
|
redis:
|
||||||
|
# Redis数据库索引(默认为0)
|
||||||
|
database: 0
|
||||||
|
# Redis服务器地址
|
||||||
|
host: 127.0.0.1
|
||||||
|
# Redis服务器连接端口
|
||||||
|
port: 6379
|
||||||
|
# Redis服务器连接密码(默认为空)
|
||||||
|
password:
|
||||||
|
# 连接超时时间
|
||||||
|
timeout: 10s
|
||||||
|
lettuce:
|
||||||
|
pool:
|
||||||
|
# 连接池最大连接数
|
||||||
|
max-active: 200
|
||||||
|
# 连接池最大阻塞等待时间(使用负值表示没有限制)
|
||||||
|
max-wait: -1ms
|
||||||
|
# 连接池中的最大空闲连接
|
||||||
|
max-idle: 10
|
||||||
|
# 连接池中的最小空闲连接
|
||||||
|
min-idle: 0
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
12
sa-token-demo/sa-token-demo-websocket/.gitignore
vendored
Normal file
12
sa-token-demo/sa-token-demo-websocket/.gitignore
vendored
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
target/
|
||||||
|
|
||||||
|
node_modules/
|
||||||
|
bin/
|
||||||
|
.settings/
|
||||||
|
unpackage/
|
||||||
|
.classpath
|
||||||
|
.project
|
||||||
|
|
||||||
|
.idea/
|
||||||
|
|
||||||
|
.factorypath
|
69
sa-token-demo/sa-token-demo-websocket/pom.xml
Normal file
69
sa-token-demo/sa-token-demo-websocket/pom.xml
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
<groupId>cn.dev33</groupId>
|
||||||
|
<artifactId>sa-token-demo-websocket</artifactId>
|
||||||
|
<version>0.0.1-SNAPSHOT</version>
|
||||||
|
|
||||||
|
<!-- SpringBoot -->
|
||||||
|
<parent>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-parent</artifactId>
|
||||||
|
<version>2.0.0.RELEASE</version>
|
||||||
|
<!-- <version>1.5.9.RELEASE</version> -->
|
||||||
|
<relativePath/>
|
||||||
|
</parent>
|
||||||
|
|
||||||
|
<!-- 定义sa-token版本号 -->
|
||||||
|
<properties>
|
||||||
|
<sa-token-version>1.29.0</sa-token-version>
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
|
||||||
|
<!-- SpringBoot依赖 -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-web</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-aop</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- WebScoket 依赖 -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-websocket</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- Sa-Token 权限认证, 在线文档:http://sa-token.dev33.cn/ -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>cn.dev33</groupId>
|
||||||
|
<artifactId>sa-token-spring-boot-starter</artifactId>
|
||||||
|
<version>${sa-token-version}</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- Sa-Token整合 Redis (使用jackson序列化方式) -->
|
||||||
|
<!-- <dependency>
|
||||||
|
<groupId>cn.dev33</groupId>
|
||||||
|
<artifactId>sa-token-dao-redis-jackson</artifactId>
|
||||||
|
<version>${sa-token-version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.commons</groupId>
|
||||||
|
<artifactId>commons-pool2</artifactId>
|
||||||
|
</dependency> -->
|
||||||
|
|
||||||
|
<!-- @ConfigurationProperties -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-configuration-processor</artifactId>
|
||||||
|
<optional>true</optional>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
|
||||||
|
</project>
|
@ -0,0 +1,32 @@
|
|||||||
|
package com.pj;
|
||||||
|
|
||||||
|
import org.springframework.boot.SpringApplication;
|
||||||
|
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||||
|
|
||||||
|
import cn.dev33.satoken.SaManager;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sa-Token 整合 WebSocket 鉴权示例
|
||||||
|
* @author kong
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@SpringBootApplication
|
||||||
|
public class SaTokenWebSocketApplication {
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 1、访问登录接口,拿到会话Token:
|
||||||
|
* http://localhost:8081/acc/doLogin?name=zhang&pwd=123456
|
||||||
|
*
|
||||||
|
* 2、找一个WebSocket在线测试页面进行连接,
|
||||||
|
* 例如:
|
||||||
|
* https://www.bejson.com/httputil/websocket/
|
||||||
|
* 然后连接地址:
|
||||||
|
* ws://localhost:8081/ws-connect/2e6db38f-1e78-40bc-aa8f-e8f1f77fbef5
|
||||||
|
*/
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
SpringApplication.run(SaTokenWebSocketApplication.class, args);
|
||||||
|
System.out.println("\n启动成功:Sa-Token配置如下:" + SaManager.getConfig());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,48 @@
|
|||||||
|
package com.pj.test;
|
||||||
|
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
import cn.dev33.satoken.stp.StpUtil;
|
||||||
|
import cn.dev33.satoken.util.SaResult;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 登录测试
|
||||||
|
* @author kong
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/acc/")
|
||||||
|
public class LoginController {
|
||||||
|
|
||||||
|
// 测试登录 ---- http://localhost:8081/acc/doLogin?name=zhang&pwd=123456
|
||||||
|
@RequestMapping("doLogin")
|
||||||
|
public SaResult doLogin(String name, String pwd) {
|
||||||
|
// 此处仅作模拟示例,真实项目需要从数据库中查询数据进行比对
|
||||||
|
if("zhang".equals(name) && "123456".equals(pwd)) {
|
||||||
|
StpUtil.login(10001);
|
||||||
|
return SaResult.ok("登录成功").set("token", StpUtil.getTokenValue());
|
||||||
|
}
|
||||||
|
return SaResult.error("登录失败");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 查询登录状态 ---- http://localhost:8081/acc/isLogin
|
||||||
|
@RequestMapping("isLogin")
|
||||||
|
public SaResult isLogin() {
|
||||||
|
return SaResult.ok("是否登录:" + StpUtil.isLogin());
|
||||||
|
}
|
||||||
|
|
||||||
|
// 查询 Token 信息 ---- http://localhost:8081/acc/tokenInfo
|
||||||
|
@RequestMapping("tokenInfo")
|
||||||
|
public SaResult tokenInfo() {
|
||||||
|
return SaResult.data(StpUtil.getTokenInfo());
|
||||||
|
}
|
||||||
|
|
||||||
|
// 测试注销 ---- http://localhost:8081/acc/logout
|
||||||
|
@RequestMapping("logout")
|
||||||
|
public SaResult logout() {
|
||||||
|
StpUtil.logout();
|
||||||
|
return SaResult.ok();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,18 @@
|
|||||||
|
package com.pj.ws;
|
||||||
|
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.web.socket.server.standard.ServerEndpointExporter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 开启WebSocket支持
|
||||||
|
*/
|
||||||
|
@Configuration
|
||||||
|
public class WebSocketConfig {
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public ServerEndpointExporter serverEndpointExporter() {
|
||||||
|
return new ServerEndpointExporter();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,102 @@
|
|||||||
|
package com.pj.ws;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
|
import javax.websocket.OnClose;
|
||||||
|
import javax.websocket.OnError;
|
||||||
|
import javax.websocket.OnMessage;
|
||||||
|
import javax.websocket.OnOpen;
|
||||||
|
import javax.websocket.Session;
|
||||||
|
import javax.websocket.server.PathParam;
|
||||||
|
import javax.websocket.server.ServerEndpoint;
|
||||||
|
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import cn.dev33.satoken.exception.SaTokenException;
|
||||||
|
import cn.dev33.satoken.stp.StpUtil;
|
||||||
|
import cn.dev33.satoken.util.SaFoxUtil;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* WebSocket 连接测试
|
||||||
|
*/
|
||||||
|
@Component
|
||||||
|
@ServerEndpoint("/ws-connect/{satoken}")
|
||||||
|
public class WebSocketConnect {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 固定前缀
|
||||||
|
*/
|
||||||
|
private static final String USER_ID = "user_id_";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 存放Session集合,方便推送消息 (javax.websocket.Session)
|
||||||
|
*/
|
||||||
|
private static ConcurrentHashMap<String, Session> sessionMap = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
|
// 监听:连接成功
|
||||||
|
@OnOpen
|
||||||
|
public void onOpen(Session session, @PathParam("satoken") String satoken) throws IOException {
|
||||||
|
|
||||||
|
// 根据 token 获取对应的 userId
|
||||||
|
Object loginId = StpUtil.getLoginIdByToken(satoken);
|
||||||
|
if(loginId == null) {
|
||||||
|
session.close();
|
||||||
|
throw new SaTokenException("连接失败,无效Token:" + satoken);
|
||||||
|
}
|
||||||
|
|
||||||
|
// put到集合,方便后续操作
|
||||||
|
long userId = SaFoxUtil.getValueByType(loginId, long.class);
|
||||||
|
sessionMap.put(USER_ID + userId, session);
|
||||||
|
|
||||||
|
// 给个提示
|
||||||
|
String tips = "Web-Socket 连接成功,sid=" + session.getId() + ",userId=" + userId;
|
||||||
|
System.out.println(tips);
|
||||||
|
sendMessage(session, tips);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 监听: 连接关闭
|
||||||
|
@OnClose
|
||||||
|
public void onClose(Session session) {
|
||||||
|
System.out.println("连接关闭,sid=" + session.getId());
|
||||||
|
for (String key : sessionMap.keySet()) {
|
||||||
|
if(sessionMap.get(key).getId().equals(session.getId())) {
|
||||||
|
sessionMap.remove(key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 监听:收到客户端发送的消息
|
||||||
|
@OnMessage
|
||||||
|
public void onMessage(Session session, String message) {
|
||||||
|
System.out.println("sid为:" + session.getId() + ",发来:" + message);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 监听:发生异常
|
||||||
|
@OnError
|
||||||
|
public void onError(Session session, Throwable error) {
|
||||||
|
System.out.println("sid为:" + session.getId() + ",发生错误");
|
||||||
|
error.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---------
|
||||||
|
|
||||||
|
// 向指定客户端推送消息
|
||||||
|
public static void sendMessage(Session session, String message) {
|
||||||
|
try {
|
||||||
|
System.out.println("向sid为:" + session.getId() + ",发送:" + message);
|
||||||
|
session.getBasicRemote().sendText(message);
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 向指定用户推送消息
|
||||||
|
public static void sendMessage(long userId, String message) {
|
||||||
|
Session session = sessionMap.get(USER_ID + userId);
|
||||||
|
if(session != null) {
|
||||||
|
sendMessage(session, message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,49 @@
|
|||||||
|
# 端口
|
||||||
|
server:
|
||||||
|
port: 8081
|
||||||
|
|
||||||
|
# sa-token配置
|
||||||
|
sa-token:
|
||||||
|
# token名称 (同时也是cookie名称)
|
||||||
|
token-name: satoken
|
||||||
|
# token有效期,单位s 默认30天, -1代表永不过期
|
||||||
|
timeout: 2592000
|
||||||
|
# token临时有效期 (指定时间内无操作就视为token过期) 单位: 秒
|
||||||
|
activity-timeout: -1
|
||||||
|
# 是否允许同一账号并发登录 (为true时允许一起登录, 为false时新登录挤掉旧登录)
|
||||||
|
is-concurrent: true
|
||||||
|
# 在多人登录同一账号时,是否共用一个token (为true时所有登录共用一个token, 为false时每次登录新建一个token)
|
||||||
|
is-share: true
|
||||||
|
# token风格
|
||||||
|
token-style: uuid
|
||||||
|
# 是否输出操作日志
|
||||||
|
is-log: false
|
||||||
|
|
||||||
|
spring:
|
||||||
|
# redis配置
|
||||||
|
redis:
|
||||||
|
# Redis数据库索引(默认为0)
|
||||||
|
database: 0
|
||||||
|
# Redis服务器地址
|
||||||
|
host: 127.0.0.1
|
||||||
|
# Redis服务器连接端口
|
||||||
|
port: 6379
|
||||||
|
# Redis服务器连接密码(默认为空)
|
||||||
|
password:
|
||||||
|
# 连接超时时间
|
||||||
|
timeout: 10s
|
||||||
|
lettuce:
|
||||||
|
pool:
|
||||||
|
# 连接池最大连接数
|
||||||
|
max-active: 200
|
||||||
|
# 连接池最大阻塞等待时间(使用负值表示没有限制)
|
||||||
|
max-wait: -1ms
|
||||||
|
# 连接池中的最大空闲连接
|
||||||
|
max-idle: 10
|
||||||
|
# 连接池中的最小空闲连接
|
||||||
|
min-idle: 0
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -120,6 +120,8 @@ implementation 'cn.dev33:sa-token-core:${sa.top.version}'
|
|||||||
├── sa-token-demo-sso-client-h5 // [示例] Sa-Token 集成 SSO单点登录-client应用端 (前后端分离)
|
├── sa-token-demo-sso-client-h5 // [示例] Sa-Token 集成 SSO单点登录-client应用端 (前后端分离)
|
||||||
├── sa-token-demo-oauth2-server // [示例] Sa-Token 集成 OAuth2.0 (服务端)
|
├── sa-token-demo-oauth2-server // [示例] Sa-Token 集成 OAuth2.0 (服务端)
|
||||||
├── sa-token-demo-oauth2-client // [示例] Sa-Token 集成 OAuth2.0 (客户端)
|
├── sa-token-demo-oauth2-client // [示例] Sa-Token 集成 OAuth2.0 (客户端)
|
||||||
|
├── sa-token-demo-websocket // [示例] Sa-Token 集成 Web-Socket 鉴权示例
|
||||||
|
├── sa-token-demo-websocket-spring // [示例] Sa-Token 集成 Web-Socket(Spring封装版) 鉴权示例
|
||||||
├── sa-token-test // [测试] Sa-Token 单元测试合集
|
├── sa-token-test // [测试] Sa-Token 单元测试合集
|
||||||
├── sa-token-core-test // [测试] Sa-Token Core核心包单元测试
|
├── sa-token-core-test // [测试] Sa-Token Core核心包单元测试
|
||||||
├── sa-token-springboot-test // [测试] Sa-Token SpringBoot 整合测试
|
├── sa-token-springboot-test // [测试] Sa-Token SpringBoot 整合测试
|
||||||
|
Loading…
Reference in New Issue
Block a user