spring-boot + VUE 实现登录token验证,前后台获取当前登录人信息 三部曲(三)

通过自定义 @CurrentUser 获取当前登录用户

1、定义 @CurrenUser注解

package com.presoft.wydl.common.config;

import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import java.lang.annotation.RetentionPolicy;

import java.lang.annotation.ElementType;
@Target(ElementType.PARAMETER)          // 可用在方法的参数上
@Retention(RetentionPolicy.RUNTIME)     // 运行时有效
public @interface CurrentUser {
	
}

2、添加参数解析器 

要想 @CurrentUser 起作用,需要编写一个配套解析器,做法是实现 spring 提供的 HandlerMethodArgumentResolver 接口。

package com.presoft.wydl.common.config;

import org.springframework.context.annotation.Configuration;
import org.springframework.core.MethodParameter;
import org.springframework.web.bind.support.WebDataBinderFactory;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.method.support.ModelAndViewContainer;
import org.springframework.web.multipart.support.MissingServletRequestPartException;

import com.presoft.wydl.packs.system.model.UserInfo;


@Configuration
public class CurrentUserMethodArgumentResolver implements HandlerMethodArgumentResolver {

	@Override
    public boolean supportsParameter(MethodParameter parameter) {
        return parameter.getParameterType().isAssignableFrom(UserInfo.class)
                && parameter.hasParameterAnnotation(CurrentUser.class);
    }

    @Override
    public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {
        //取出第二节中放入请求中的用户信息
    	UserInfo user = (UserInfo)webRequest.getAttribute("currentUser", RequestAttributes.SCOPE_REQUEST);
        if (user != null) {
            return user;
        }
        throw new MissingServletRequestPartException("currentUser");
    }

}

3、配置参数解析器

在 WebMvcConfigurer.java 中 Override addArgumentResolvers 方法

//@Configuration
public class InterceptorConfig extends   WebMvcConfigurationSupport {
	
    @Override
    public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
        super.addArgumentResolvers(argumentResolvers);
        argumentResolvers.add(new CurrentUserMethodArgumentResolver());
    }
}

4、实例

@ApiOperation("获取企业信息")
	@RequestMapping(value = "/list",method = RequestMethod.POST)
	public Response list(EnterpriseVo vo,@CurrentUser UserInfo user) {
		return enterpriseService.selectByParams(vo);
	}

5、 文件目录 

原文 https://www.jianshu.com/p/01a6a61d9e02

  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
实现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!' } }) ``` 注意:本示例仅供参考,实际使用时需要根据实际需求进行修改和完善。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值