【转】SpringBoot+SpringCloud实现登录用户信息在微服务之间的传递

实现思路:

1:准备一个ThreadLocal变量,供线程之间共享。

2:每个微服务对所有过来的Feign调用进行过滤,然后从请求头中获取User用户信息,并存在ThreadLocal变量中。

3:每个微服务在使用FeignClient调用别的微服务时,先从ThreadLocal里面取出user信息,并放在request的请求头中。

4:封装为一个注解,在启动类上标记即可。

代码样例:

1:ThreadLocal工具类 :UserInfoContext

package com.test.domi.common.system;

import com.test.domi.dao.UserInfo;

public class UserInfoContext {
    private static ThreadLocal<UserInfo> userInfo = new ThreadLocal<UserInfo>();
    public static String KEY_USERINFO_IN_HTTP_HEADER = "X-AUTO-FP-USERINFO";

    public UserInfoContext() {
    }

    public static UserInfo getUser(){
        return (UserInfo)userInfo.get();
    }

    public static void setUser(UserInfo user){
        userInfo.set(user);
    }
}

2:准备承载用户信息的userInfo实体类(代码略)

3:编写拦截器 : TransmitUserInfoFeighClientIntercepter

package com.test.domi.config;

import com.alibaba.fastjson.JSON;
import com.test.domi.common.system.UserInfoContext;
import com.test.domi.dao.UserInfo;
import feign.RequestInterceptor;
import feign.RequestTemplate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;

public class TransmitUserInfoFeighClientIntercepter implements RequestInterceptor {

    private static final Logger log = LoggerFactory.getLogger(TransmitUserInfoFeighClientIntercepter.class);
    public TransmitUserInfoFeighClientIntercepter() {
    }

    @Override
    public void apply(RequestTemplate requestTemplate) {
        //从应用上下文中取出user信息,放入Feign的请求头中
        UserInfo user = UserInfoContext.getUser();
        if (user != null) {
            try {
                String userJson = JSON.toJSONString(user);
                requestTemplate.header("KEY_USERINFO_IN_HTTP_HEADER",new String[]{URLDecoder.decode(userJson,"UTF-8")});
            } catch (UnsupportedEncodingException e) {
                log.error("用户信息设置错误",e);
            }
        }
    }
}

4:编写过滤器:TransmitUserInfoFilter

package com.test.domi.config;

import com.alibaba.fastjson.JSON;
import com.test.domi.common.system.UserInfoContext;
import com.test.domi.dao.UserInfo;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;

public class TransmitUserInfoFilter implements Filter {

    private static final Logger log = LoggerFactory.getLogger(TransmitUserInfoFeighClientIntercepter.class);
    public TransmitUserInfoFilter() {
    }
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
    }
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
       this.initUserInfo((HttpServletRequest)request);
       chain.doFilter(request,response);
    }

    private void initUserInfo(HttpServletRequest request){
        String userJson = request.getHeader("KEY_USERINFO_IN_HTTP_HEADER");
        if (StringUtils.isNotBlank(userJson)) {
            try {
                userJson = URLDecoder.decode(userJson,"UTF-8");
                UserInfo userInfo = (UserInfo) JSON.parseObject(userJson,UserInfo.class);
                //将UserInfo放入上下文中
                UserInfoContext.setUser(userInfo);
            } catch (UnsupportedEncodingException e) {
               log.error("init userInfo error",e);
            }
        }
    }

    @Override
    public void destroy() {
    }
}

5:编写注解实现类: EnableUserInfoTransmitterAutoConfiguration


package spring.cloud.common.config;

import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import spring.cloud.common.interceptor.TransmitUserInfoFeighClientInterceptor;import spring.cloud.common.filter.TransmitUserInfoFilter;

//@Configuration 在业务端通过注解EanbleUserInfoTransmitter加载
public class EnableUserInfoTransmitterAutoConfiguration {

    public EnableUserInfoTransmitterAutoConfiguration() {    }

    @Bean    public TransmitUserInfoFeighClientInterceptor transmitUserInfo2FeighHttpHeader(){        System.out.println("-----TransmitUserInfoFeighClientInterceptor");        return new TransmitUserInfoFeighClientInterceptor();    }

    @Bean    public TransmitUserInfoFilter transmitUserInfoFromHttpHeader(){        System.out.println("-----TransmitUserInfoFilter");        return new TransmitUserInfoFilter();    }}
 

6:编写注解 EnableUserInfoTransmitter

package com.test.domi.annotation;

import com.test.domi.config.EnableUserInfoTransmitterAutoConfiguration;
import org.springframework.context.annotation.Import;

import java.lang.annotation.*;

@Documented
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Import({EnableUserInfoTransmitterAutoConfiguration.class})
public @interface EnableUserInfoTransmitter {
}

7:在启动类上标记注解即可使用(无侵入)

package com.test.domi;

import com.test.domi.annotation.EnableUserInfoTransmitter;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;

@EnableDiscoveryClient
@SpringBootApplication
@MapperScan("com.test.domi.dao")
@EnableUserInfoTransmitter
public class TestCommonClient {

    public static void main(String[] args){

        SpringApplication.run(TestCommonClient.class,args);
    }
}

转载自:https://www.cnblogs.com/domi22/p/9248536.html

原文地址:https://www.cnblogs.com/iwenwen/p/11840764.html

时间: 2024-07-31 10:46:23

【转】SpringBoot+SpringCloud实现登录用户信息在微服务之间的传递的相关文章

SpringBoot+SpringCloud实现登录用户信息在微服务之间的传递

实现思路: 1:准备一个ThreadLocal变量,供线程之间共享. 2:每个微服务对所有过来的Feign调用进行过滤,然后从请求头中获取User用户信息,并存在ThreadLocal变量中. 3:每个微服务在使用FeignClient调用别的微服务时,先从ThreadLocal里面取出user信息,并放在request的请求头中. 4:封装为一个注解,在启动类上标记即可. 代码样例: 1:ThreadLocal工具类 :UserInfoContext package com.test.domi

利用html5的本地存储功能实现登录用户信息保存

在HTML5中,本地存储是一个window的属性,包括localStorage和sessionStorage,从名字应该可以很清楚的辨认二者的区别,前者是一直存在本地的,后者只是伴随着session,窗口一旦关闭就没了.二者用法完全相同,这里以localStorage为例. 用户名.密码保存,自动登录等,可以通过设置cookie实现,第一次登录网站后在本地计算机的中写入cookie,之后再次登录此网站查看cookie中现有的值,用cookie值进行网站登录即可.但是 cookie 不适合大量数据

Spring Security应用开发(12) 获取已登录用户信息

1.1. 获取已登录用户信息 在使用Spring Security的应用程序中,可以通过SecurityContext接口获取到已经登录的用户的信息.SecurityContext接口的实例通过SecurityContextHolder的静态方法getContext()获取. 通过SecurityContext可以获取到Authentication接口的实例,而通过Authentication接口可以获取到: principal:主角,通常是一个UserDetails接口的实例,而默认就是Use

利用Application对象存储登录用户信息

Application对象非常适合用于存储一些与整个应用相关数据,例如应用版本,应用登录账户,数据缓存等. 如activity的切换是很频繁的,差不多可以和一个网站中不同网页之间的切换一样,那么不同的activity之间需要存储公共信息(如只有一个当前登录用户)以及数据传递等. 利用Application对象存储登录用户信息的方法,可以很方便的不同activity之间获取登录用户信息. 首先,新建一个java类继承Application类:BaseApplication.java import

Linux 查看登录用户信息 who &amp; whoami

Linux 查看登录用户信息 who & whoami 在一台服务器上,同一时间往往会有很难多人同时登录. who 命令可以查看当前系统中有哪些人登录,以及他们都工作在哪个控制台上. 这样可以很方便的监控机器的登录人信息,并对系统操作进行安全监控. [[email protected] /]# who root pts/0 2019-11-21 23:10 (XX..) root pts/2 2019-11-18 11:39 (XX..) 效果如下: 有时候,可能会忘记自己是以什么身份登录到系统

Linux下用于查看系统当前登录用户信息的4种方法

作为系统管理员,你可能经常会(在某个时候)需要查看系统中有哪些用户正在活动.有些时候,你甚至需要知道他(她)们正在做什么.本文为我们总结了4种查看系统用户信息(通过编号(ID))的方法. 1. 使用w命令查看登录用户正在使用的进程信息 w命令用于显示已经登录系统的用户的名称,以及他们正在做的事.该命令所使用的信息来源于/var/run/utmp文件.w命令输出的信息包括:?用户名称 ?用户的机器名称或tty号 ?远程主机地址 ?用户登录系统的时间 ?空闲时间(作用不大) ?附加到tty(终端)的

Centos-当前登录用户信息- w who

w who 显示当前登录系统的用户,但w显示的更为详细 who 相关参数 # 默认输出 用户名.登录终端.登录时间 -a 列出所有信息 -b    系统最近启动日期 -m   当前终端信息,相当于 who am i -q 列出当前登录用户并统计用户数量 -r 显示当前系统运行级别 -u 显得当前每个用户的用户名.登录终端.登录时间.终端活动.进程标识 -w 显示tty状态, + 任何人可写, - 仅对root用户或所有者可写, ? 终端故障 who显示的信息 1. 用户名 2. 状态,终端是否可

spring-如何优雅的获取登录用户信息

这个问题其实一直比较困扰我. 因为在业务逻辑中经常会使用当前登录用户的一些信息,比如user_id等 而如果使用shiro做登录.权限验证……那么获取用户信息就需要 String username = SecurityUtils.getSubject().getPrincipal(); ……这简直就是蛋疼了……虽然这么用也不是不成 谁有更好的解决办法吗? 原文地址:https://www.cnblogs.com/kalajiadisi/p/11050308.html

Django2集成xadmin详解-5-获取登录用户信息并填充相应Model字段

一 场景问题继续使用IDC Model,在此Model增加user字段,用于记录添加当前数据的用户: class IDC(models.Model): user = models.ForeignKey(User, on_delete=models.CASCADE, editable=False, null=True) # 记录创建该数据的用户 name = models.CharField(max_length=64) contact = models.CharField(max_length=