SpringCloud服务内部的会话传递与解析

开发语言
2020-09-11 23:02:14
分享

先说说会话机制

主流的用户会话保持技术包含以下: - cookie - session - token 在微服务模式下,使用更多的是采用token机制来保持用户会话。而具体的实现会采用jwt来实现token,这样用户的会话数据会分布到用户端也不用服务器存储,但是他会消耗计算性能(jwt需要做签名校验)这里注意一定不要将敏感数据存储到jwt中,因为Base64解码后它是明文的。

SpringCloud网关

网关在收到请求后,接收用户的token,将token转义为服务内部可识别的用户信息。 例如:
token=MKLDNSLKDNLSADJASDLKDJKSA5312dfasd
通过Redis查询到用户的基本信息
{
    "userId": 1,
    "roles":[
       "ADMIN", "MEMBER"
     ] 
}
网关将转发解析后 的用户数据通过HTTP请求头转发到具体调用的服务。这样被调用的服务就能通过请求头得到那串JSON数据。从而得到 用户的ID甚至更多的用户信息。

具体的内部服务获取用户信息实现

这里可以使用注解 ,通过Spring的参数拦截转换请求头的json数据为具体控制器的参数。

/** * 获取用户信息 */ @GetMapping("/info") public Result info(@JwtUser Session session) { MerchantUserInfoVO vo = merchantSellerService.getUserInfoByUserId(session.getUserId()); if (vo == null) return Result.fail(SystemErrorType.ACCOUNT_NOT_FOUND); return Result.success(vo); }
自定义注解代码

import java.lang.annotation.*; /** * JWT获取登录用户注解 * * @author marker * @create 2018-05-28 14:06 **/ @Documented @Target({ElementType.PARAMETER}) @Retention(RetentionPolicy.RUNTIME) public @interface JwtUser { String value() default ""; }
拦截带JWTUSER注解的 请求参数

import com.alibaba.fastjson.JSON; import com.springboot.cloud.common.core.annotation.JwtUser; import com.springboot.cloud.common.core.entity.session.SessionUser; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang.StringUtils; import org.springframework.core.MethodParameter; import org.springframework.web.bind.annotation.ControllerAdvice; import org.springframework.web.bind.support.WebDataBinderFactory; import org.springframework.web.context.request.NativeWebRequest; import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.context.request.ServletRequestAttributes; import org.springframework.web.method.support.HandlerMethodArgumentResolver; import org.springframework.web.method.support.ModelAndViewContainer; import javax.servlet.http.HttpServletRequest; import static com.springboot.common.web.interceptor.UserInterceptor.X_CLIENT_TOKEN_USER; /** * Jwt User参数解析器 * * @author marker * @create 2018-05-28 14:08 **/ @Slf4j @ControllerAdvice public class JwtUserHandlerMethodArgumentResolver implements HandlerMethodArgumentResolver { @Override public boolean supportsParameter(MethodParameter parameter) { if (parameter.hasParameterAnnotation(JwtUser.class)) { log.debug("JwtUserHandlerMethodArgumentResolver"); return true; } return false; } @Override public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception { HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder .currentRequestAttributes()).getRequest(); // 获取如果为空设置默认值 String authorization = StringUtils.defaultIfBlank(request.getHeader(X_CLIENT_TOKEN_USER), "{}"); // 转换为对象 SessionUser sessionUser = JSON.parseObject(authorization, SessionUser.class); return sessionUser; } }
Session 实体
import java.io.Serializable;


public class Session implements Serializable {

    private Long userId;
    private String userName;
    private String client_id; 

}

内部服务明文传输的安全性

微服务内部基于内网服务器之间的数据交互,这个根据具体的行业来决定怎么处理,是否需要做加密 ,多不涉密的行业明文传输即可。 外部服务都会有防火墙,网关不会有太多的业务逻辑,用户也不可能绕过网关直接调用内部服务 。 以上根据个人能力随笔发挥。。。
The End
免责声明:本文系转载,版权归原作者所有;旨在传递信息,不代表本站观点和立场。