请教一个 Java 问题 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
Sign Up Now
For Existing Member  Sign In
Asuka0947
V2EX    Java

请教一个 Java 问题

  •  
  •   Asuka0947 Sep 1, 2023 2123 views
    This topic created in 969 days ago, the information mentioned may be changed or developed.

    目前改造一个老项目,用的 eureka+fegin 这一套 A:网页消费端 B:负责登录 C:具体业务

    A 在调用 B 完成登录后,把登录信息存储到 session 中,项目业务所有登录信息都从 session 中获取

    HttpSession session = httpServletRequest.getSession(); session.setAttribute("admin", admin);

    现在由于业务需求,需要增加 token 支持第三方登录,我就在拦截器里面做了些修改

     public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception { String token = httpServletRequest.getHeader("token"); Admin admin = getAdmin(token) // 假设已经获取到了用户 HttpSession session = httpServletRequest.getSession(); session.setAttribute("admin", admin); return true ; } 

    在登录完成后把登陆信息写到 session 中 用 postman 测试接口发现了一个问题,第一次由 A 调 C 时,在 C 业务中无法获取到 session 中的 admin 信息,null 异常,拦截器日志校验显示通过了,但是第二次调用又可以获取到 session 中的 admin 信息了。两次请求都可以在请求头了找到 token ,但是只有第一次无法获取到用户信息。 加了断点发现,第一次调用,request 并没有把 session 存放到 cookie 中放到请求头里转给 C 业务,第二次调用是有的,我看了下项目里的 fegin 转发请求头配置也是同样的,第一次请求在请求头里是找不到 cookie 的

    @Configuration public class FeignRequestInterceptor implements RequestInterceptor { @Override public void apply(RequestTemplate requestTemplate) { //通过 RequestContextHolder 获取本地请求 RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes(); if (requestAttributes == null) { System.out.println("requestAttributes is null"); return; } //获取本地线程绑定的请求对象 HttpServletRequest request = ((ServletRequestAttributes) requestAttributes).getRequest(); //给请求模板附加本地线程头部信息,主要是 cookie 信息 Enumeration<String> headerNames = request.getHeaderNames(); while (headerNames.hasMoreElements()) { String name = headerNames.nextElement(); Enumeration<String> values = request.getHeaders(name); while (values.hasMoreElements()) { String value = values.nextElement(); requestTemplate.header(name, value); } } } } 

    想询问下问题到底出在哪里了?

    3 replies    2023-09-02 11:59:48 +08:00
    mmdsun
        1
    mmdsun  
       Sep 1, 2023 via iPhone
    “第一次调用,request 并没有把 session 存放到 cookie 中放到请求头里转给 C 业务,第二次调用是有的。”

    这么看可能还是 RequestInterceptor 拦截器的问题,是不是多线程的环境?比如有异步注解,或者断路器? RequestInterceptor 加个打印当前线程 ID 看看,feign 客户端开启详细请求日志看看。

    看起来是通过转发 cookie 实现登录状态的吧!建议统一用 token 登录。spring session 也能配置,加个 HeaderHttpSessionIdResolver.xAuthToken ,向下游传个 ID ,就能拿到会话状态了。
    ZZ74
        2
    ZZ74  
       Sep 1, 2023
    第一次调用 Admin admin = getAdmin(token)
    返回了 null 也就是 admin 是 null

    B 服务给你 token 后没及时写入信息到缓存或者数据库中

    然而这又有什么用呢 我还是失业中... 哈哈
    zm8m93Q1e5otOC69
        3
    zm8m93Q1e5otOC69  
       Sep 2, 2023
    分布式 session 问题把,用 redis 存一下?
    About     Help     Advertise     Blog     API     FAQ     Solana     3222 Online   Highest 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 36ms UTC 14:11 PVG 22:11 LAX 07:11 JFK 10:11
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86