spring boot+vue+websocket带token身份认证推送消息实现
时间: 2023-08-02 15:08:41 浏览: 243
springboot+jwt实现token登陆权限认证的实现
5星 · 资源好评率100%
要实现Spring Boot + Vue + WebSocket带Token身份认证推送消息,可以按照以下步骤进行:
1.在Spring Boot中配置WebSocket,包括WebSocket配置类、WebSocket处理器、WebSocket拦截器等。
2.在Vue中使用WebSocket连接到后端WebSocket服务,可以使用Vue-WebSocket插件来实现。
3.在后端WebSocket连接建立时,验证用户身份,可以使用JWT Token来进行身份认证。在用户登录成功后,生成JWT Token并返回给前端,前端在连接WebSocket时将JWT Token放入请求头中。
4.后端WebSocket服务在接收到WebSocket连接请求后,从请求头中获取JWT Token,并使用JWT Token验证用户身份。
5.验证通过后,将WebSocket连接信息保存到WebSocket连接池中,可以使用ConcurrentHashMap来保存WebSocket连接信息。
6.当需要向用户推送消息时,从WebSocket连接池中获取对应的WebSocket连接,并向连接中发送消息即可。
下面是一个简单的示例代码,仅供参考:
后端Spring Boot代码:
WebSocket配置类:
```java
@Configuration
@EnableWebSocket
public class WebSocketConfig implements WebSocketConfigurer {
@Override
public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
registry.addHandler(webSocketHandler(), "/ws")
.addInterceptors(new WebSocketInterceptor())
.setAllowedOrigins("*");
}
@Bean
public WebSocketHandler webSocketHandler() {
return new MyWebSocketHandler();
}
}
```
WebSocket处理器:
```java
public class MyWebSocketHandler extends TextWebSocketHandler {
private static final Map<Long, WebSocketSession> sessionPool = new ConcurrentHashMap<>();
@Override
public void afterConnectionEstablished(WebSocketSession session) throws Exception {
Long userId = getUserIdFromToken(session);
if (userId == null) {
session.close();
return;
}
sessionPool.put(userId, session);
}
@Override
public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
Long userId = getUserIdFromToken(session);
if (userId != null) {
sessionPool.remove(userId);
}
}
private Long getUserIdFromToken(WebSocketSession session) {
HttpHeaders headers = session.getHandshakeHeaders();
String token = headers.getFirst("Authorization");
if (StringUtils.isEmpty(token)) {
return null;
}
try {
Claims claims = Jwts.parser().setSigningKey("secret").parseClaimsJws(token).getBody();
Long userId = Long.parseLong(claims.getSubject());
return userId;
} catch (Exception e) {
return null;
}
}
public static void sendMessage(Long userId, String message) throws IOException {
WebSocketSession session = sessionPool.get(userId);
if (session != null) {
session.sendMessage(new TextMessage(message));
}
}
}
```
WebSocket拦截器:
```java
public class WebSocketInterceptor implements HandshakeInterceptor {
@Override
public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, Map<String, Object> attributes) throws Exception {
HttpHeaders headers = request.getHeaders();
String token = headers.getFirst("Authorization");
if (StringUtils.isEmpty(token)) {
response.setStatusCode(HttpStatus.UNAUTHORIZED);
return false;
}
try {
Claims claims = Jwts.parser().setSigningKey("secret").parseClaimsJws(token).getBody();
Long userId = Long.parseLong(claims.getSubject());
attributes.put("userId", userId);
return true;
} catch (Exception e) {
response.setStatusCode(HttpStatus.UNAUTHORIZED);
return false;
}
}
@Override
public void afterHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, Exception ex) {
}
}
```
控制器:
```java
@RestController
public class WebSocketController {
@GetMapping("/push")
public void push(@RequestParam("userId") Long userId, @RequestParam("message") String message) throws IOException {
MyWebSocketHandler.sendMessage(userId, message);
}
}
```
前端Vue代码:
```javascript
import Vue from 'vue'
import VueWebSocket from 'vue-websocket'
Vue.use(VueWebSocket, 'ws://localhost:8080/ws', {
reconnection: true,
reconnectionAttempts: 5,
reconnectionDelay: 3000,
format: 'json',
passToStoreHandler: function (eventName, event) {
if (!eventName.startsWith('SOCKET_')) { return }
let method = 'commit'
let target = eventName.toUpperCase()
let msg = event
Vue.store[method](target, msg)
}
})
// 登录成功后保存JWT Token到localStorage中
localStorage.setItem('jwtToken', 'xxxxx')
// 连接WebSocket并带上JWT Token
Vue.prototype.$socket = Vue.prototype.$connect({
format: 'json',
passToStoreHandler: true,
reconnection: true,
reconnectionAttempts: 5,
reconnectionDelay: 3000,
queryParams: {
Authorization: localStorage.getItem('jwtToken')
}
})
```
使用时,可以调用WebSocketController的push接口向指定用户推送消息,例如:
```javascript
this.$http.get('/push', { params: { userId: 123, message: 'Hello, World!' } })
```
注意:本示例仅供参考,实际使用时需要根据实际需求进行修改和完善。
阅读全文