@CurrentUser获取当前登录用户信息

告别抖动与滞后:深入博能传动伺服DSC功能,用105报文提升多轴同步性能 本文深入解析博能传动伺服DSC功能如何通过105报文实现多轴同步性能提升,有效解决工业自动化中的抖动与滞后问题。详细介绍了DSC技术原理、105报文实现机制及多轴同步工程实践,帮助工程师优化伺服系统性能,实现绝对齿轮同步。 阅读详情
AI摘要

本文介绍了一种基于Token的身份验证机制实现方案,包括使用UUID生成唯一标识符、利用注解简化登录用户信息获取流程、配置拦截器确保接口安全性等方面。

首先创建一个项目,项目需要有登录的功能。

1、首先需要用到token,在用户表中存放一个token,每当用户登录的时候就用UUID生成一个token替换之前的token,并保存(修改)到缓存中。

2、创建@CurrentUser注解。

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

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

3、写一个组件,用来存放和取出token

@Component
public class UserCache {

    private static final String HELPER_KEY="user:temp:";

    private static UserCache userCache;
    @Resource
    private TestUserService testUserService;
    @Resource
    private RedisTemplate<String, TestUser> redisTemplate;

    @PostConstruct
    public void init() {
        userCache = this;
        userCache.testUserService = this.testUserService;
        userCache.redisTemplate=this.redisTemplate;
    }

    /**
     * 服务器端的本地缓存时间为24小时
     */
    private static final long EXPIRE_TIME = 24L;
    /**
     * 根据token获取Pregnant对象
     *
     * @param token
     * @return
     */
    public static TestUser getUserByToken(String token) {
        TestUser testUser = userCache.redisTemplate.boundValueOps(HELPER_KEY + token).get();
        if (testUser == null){
            TestUser helper = userCache.testUserService.
                    findByToken(token);
            if (helper == null){
                throw new UnauthorizedException(ErrorCode.Unauthorized);
            }
            userCache.redisTemplate.boundValueOps(HELPER_KEY+token).set(testUser,EXPIRE_TIME, TimeUnit.HOURS);
        }
        return testUser;
    }

    /**
     * 主动放入缓存
     *
     * @param token
     * @param dto
     */
    public static void put(String token, TestUser dto) {
        userCache.redisTemplate.boundValueOps(HELPER_KEY+token).set(dto,EXPIRE_TIME,TimeUnit.HOURS);
    }

4、配置PublicInterface(用来标注可以不使用token)

@Target(ElementType.METHOD)          // 可用在方法的参数上
@Retention(RetentionPolicy.RUNTIME)     // 运行时有效
public @interface PublicInterface {
}

5、配置一个拦截器,判断是否存在token和token是否有效

public class AuthenticationInterceptor implements HandlerInterceptor {

    /**
     * 存储URL
     */
    protected final static Set<String> ignoreUrls = ConcurrentHashMap.newKeySet();

    private Logger logger = LoggerFactory.getLogger(AuthenticationInterceptor.class);
    //不拦截哪些请求
    static {
        ignoreUrls.add("/error");
        ignoreUrls.add("/images");
        ignoreUrls.add("/static");
        ignoreUrls.add("/webjars");
        ignoreUrls.add("/Users/login");
    }


    @Override
    public boolean preHandle(HttpServletRequest request,
                             HttpServletResponse response, Object handler) throws Exception {

        // 如果不是映射到方法直接通过
        if (!(handler instanceof HandlerMethod)) {
            return true;
        }
        HandlerMethod handlerMethod = (HandlerMethod) handler;
        Method method = handlerMethod.getMethod();

        // 判断接口是否需要登录
        PublicInterface methodAnnotation = method.getAnnotation(PublicInterface.class);
        if (methodAnnotation != null) {
            return true;
        }
        if (isIntercept(request.getServletPath())) {
            // 从http请求头中取出token
            String token = request.getHeader("token");
            if (token == null) {
                throw new UnauthorizedException(ErrorCode.TokenNotExist);
            }

            //判断token时候合法
            TestUser testUser = UserCache.getUserByToken(token);
            if (testUser == null) {
                throw new UnauthorizedException(ErrorCode.TokenInvalid);
            }

            // 将当前用户放入request以备@CurrentUser注解使用
            request.setAttribute("currentUser", testUser);
            return true;
        }
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request,
                           HttpServletResponse response, Object handler,
                           ModelAndView modelAndView) throws Exception {
    }

    @Override
    public void afterCompletion(HttpServletRequest request,
                                HttpServletResponse response, Object handler, Exception ex)
            throws Exception {
    }

    /**
     * 判断是否需要拦截
     *
     * @param servletPath
     * @return
     */
    private boolean isIntercept(String servletPath) {
        for (String url : ignoreUrls) {
            if (servletPath.startsWith(url)) {
                return false;
            }
        }
        return true;
    }

6、配置解析器,用来获取当前登录用户的信息

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

    @Override
    public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest,
                                  WebDataBinderFactory binderFactory) throws Exception {
        TestUser dto = (TestUser) webRequest.getAttribute("currentUser", RequestAttributes.SCOPE_REQUEST);
        if (dto != null) {
            return dto;
        }
        throw new MissingServletRequestPartException("currentUser");
    }
}

7、注入进程序

@Configuration
public class MyMvcConfig extends WebMvcConfigurerAdapter {

    //配置视图组件
    @Bean
    public WebMvcConfigurerAdapter webMvcConfigurerAdapter(){
        WebMvcConfigurerAdapter adapter = new WebMvcConfigurerAdapter() {
            @Override
            public void addViewControllers(ViewControllerRegistry registry) {
                registry.addViewController("/").setViewName("login");
                registry.addViewController("/login.html").setViewName("login");
                registry.addViewController("/home.html").setViewName("home");
                registry.addViewController("/employee.html").setViewName("employee");
                registry.addViewController("/addEmployee.html").setViewName("addEmployee");
                registry.addViewController("/updateEmployee.html").setViewName("updateEmployee");
            }
        };
        return adapter;
    }

    public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
        argumentResolvers.add(currentUserMethodArgumentResolver());
        super.addArgumentResolvers(argumentResolvers);
    }

    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(authenticationInterceptor())
                .addPathPatterns("/**");
        super.addInterceptors(registry);
    }
    @Bean
    public UserMethodArgumentResolver currentUserMethodArgumentResolver() {
        return new UserMethodArgumentResolver();
    }

    @Bean
    public AuthenticationInterceptor authenticationInterceptor() {
        return new AuthenticationInterceptor();
    }

8、登录的controller

@Controller
public class LoginController {

    @Resource
    TestUserService testUserService;

    @PostMapping ("/Users/login")
    @ResponseBody
    public Map<String,String> userLogin(@RequestParam("userName") String userName,
                            @RequestParam("userPass") String userPass, HttpSession session){
        Map<String,String> map = new HashMap<>();
        TestUser user = testUserService.findUserLogin(userName, userPass);
        if (user != null){
            String token = UUID.randomUUID().toString().replaceAll("-", "");
            //保存token到redis并更新数据库
            user.setToken(token);
            TestUser testUser = testUserService.updateTestUser(user);
            session.setAttribute("token",token);
            UserCache.put(token, testUser);
            map.put("result","登录成功");
        }else {
            map.put("result","用户名或密码错误");
        }
        return map;
    }
}

9、登录页面

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8"/>
    <title>Title</title>
    <script src="/js/jquery-2.1.3.min.js"></script>
</head>
<body>
    <div>
        账户:<input type="text" id="userName"/>
        <br/>
        密码:<input type="text" id="userPass"/>
        <br/>
        <input type="button" id="login" value="登录"/>
    </div>
</body>
<script>
    $("#login").click(function (){
        let userName = $("#userName").val();
        let userPass = $("#userPass").val();
        $.ajax({
            type:"POST",
            url:"/Users/login",
            data:{
                userName:userName,
                userPass:userPass
            },
            success:function (data){
                if(data.result == "登录成功"){
                    alert("登录成功");
                    window.location.href = 'http://localhost:8080/home.html';
                }else{
                    alert(data.result);
                }
            }
        })
    })
</script>
</html>

10、登录之后跳转页面

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8"/>
    <title>Title</title>
    <script src="/js/jquery-2.1.3.min.js"></script>
</head>
<body>
<input type="hidden" id="token" th:value="${session.token}"/>
<div>
    <div>运营页面</div>
    <div id="employee">员工管理</div>
    <div>用户管理</div>
    <div id="findEmployee">财务统计</div>
</div>
</body>
<script>
    $("#employee").click(function (){
        let token = $("#token").val();
        $.ajax({
            headers:{
                token:token
            },
            type:"Get",
            url:"/Users/findEmployeeAll",
            date:{},
            success:function (data){
                alert(data)
            }
        })
    })
    $("#findEmployee").click(function (){
        let token = $("#token").val();
        $.ajax({
            type:"Get",
            url:"/Users/findEmployee",
            date:{},
            success:function (data){
                alert(data)
            }
        })
    })
</script>
</html>

11、验证

    /**
     * 需要携带token的接口
     * @return
     */
    @GetMapping("/Users/findEmployeeAll")
    @ResponseBody
    public String findEmployeeAll(@CurrentUser TestUser user){
        return "这是验证token的接口"+user.getToken();
    }

    /**
     * 使用@PublicInterface,不需要携带token
     * @param user
     * @return
     */
    @GetMapping("/Users/findEmployee")
    @ResponseBody
    @PublicInterface
    public String findEmployee(TestUser user){
        return "这是验证token的接口";
    }
别再混淆了!深入浅出图解四元数姿态控制中的‘误差四元数’(附四种定义对比与仿真) 本文深入解析四元数姿态控制中的误差四元数定义差异,对比四种常见定义(如Q₀∘Q⁻¹与Q⁻¹∘Q₀)及其对PD控制性能的影响。通过刚体动力学仿真验证,揭示定义二(Q⁻¹∘Q₀)在无人机和航天器控制中的最优性能,提供工程实践建议与参数整定技巧,帮助开发者避免常见陷阱并提升控制效率。 阅读详情

相关推荐

12V INPUT电源电路设计中的关键保护机制解析【精简】

本文深入解析了12V INPUT电源电路设计中不可或缺的关键保护机制。针对常见的电源反接、过压及浪涌等风险,文章详细拆解了PMOS防反接、TVS过压钳位、OVP芯片关断以及快速断电电路等核心防护方案的设计原理、选型要点与实战优化技巧,旨在帮助工程师构建可靠、经济的电源前端防御体系。

weixin_29158047的博客 228

注解获取当前登录用户【@CurrentUser】

注解获取当前登录用户

qq_39814220的博客 627

从MRF8P9040N数据手册到ADS仿真:手把手教你搞定LDMOS功放设计(附完整模型下载)

本文详细解析了MRF8P9040N LDMOS功率放大器的数据手册关键参数,并提供了在ADS中进行仿真的完整指南。从模型导入、直流工作点验证到负载牵引与阻抗匹配设计,逐步指导工程师完成高效功放设计。文章还包含调试技巧和常见问题解决方案,帮助优化射频功放性能。

weixin_27015733的博客 488

@Currentuser注解的实现

1.在springmvc.xml中添加驱动,添加内置标签mvc:argument-resolvers,注入bean&lt;!-- 添加注解驱动 --&gt; &lt;mvc:annotation-driven validator="validator" &gt; &lt;mvc:argument-resolvers&gt; &...

LQ-QianLee的博客 7067

coredump文件的原理是啥

Core Dump(核心转储)是操作系统在程序崩溃(如段错误、非法指令等)时自动生成的一个文件,它包含了程序崩溃瞬间的。通过 core dump,开发者可以像“时间回溯”一样检查程序崩溃瞬间的状态,是调试复杂问题的利器!终止时,Linux 内核会生成 core 文件。不会生成 core dump,因为它们是“优雅终止”信号。这样 core 文件会直接压缩存储,节省磁盘空间。的文件(类似可执行文件),可以用。Core 文件本质上是一个。

二进制君 380

小梅哥Xilinx FPGA学习笔记15——基于SPI接口的ADC芯片驱动

ADC(Analog to Digital Conver),通常是指一个将转变为数字信号(二进制表示的离散信号)的转换器。先将输入模拟电压转换成时间或频率,再把中间量转换成数字量双积分型 ADC,先对输入采样电压和基准电压进行两次积分,获得与采样电压平均值成正比的时间间隔,同时用计数器对标准时钟脉冲计数。抗干扰能力强,稳定性好,但转换速度低。①并联比较型 ADC,采用各量级同时并行比较,各位输出码也是同时并行产生,转换速度快。缺点是成本高、功耗大。

m0_51430584的博客 5502

java current_自定义获取当前登录用户的注解@CurrentUser

java自定义一个获取当前登录用户的注解,如@CurrentUser,这样就不用每次request.getAttribute("xxx")这样获取了,我准备自定义一个参数注解,放在参数中使用,自定义注解代码如下。importjava.lang.annotation.Documented;importjava.lang.annotation.ElementType;importjava.lan...

weixin_35523259的博客 1438

基于ROS2 Humble和VGR数据集完整部署GADEN气体分散仿真环境及模型替换实践

文章摘要 本文详细介绍了基于ROS2 Humble和VGR数据集部署GADEN气体分散仿真环境的方法。GADEN是一款专为移动机器人嗅觉研究设计的3D仿真框架,能够精确模拟气体扩散过程并集成多种环境传感器。文章从系统配置开始,逐步指导读者完成ROS2 Humble环境的搭建、GADEN框架的编译部署,以及VGR数据集的使用。VGR数据集包含120个基于真实房屋模型的CFD仿真案例,为研究提供高度真实的测试环境。教程涵盖了常见问题的解决方案,并深入探讨了气体扩散模型参数的修改方法,为机器人嗅觉算法的开发和验证

huanghm88的专栏 273

自定义@CurrentUser参数解析获取当前登录用户

HandlerMethodArgumentResolver简介 HandlerMethodArgumentResolver接口有以下两个方法 //是否支持要转换的参数类型 boolean supportsParameter(MethodParameter parameter); //如果支持的话进行转换 @Nullable Object resolveArgument(MethodP...

new 1630

规控面试常见问题

规划控制算法常见问题。

每天进步一点点。 982

DeerFlow 系列教程 第十二篇 | Tools 工具体系——从内置工具到 MCP 扩展

文件此工具允许 Agent 在运行时创建新的自定义 Agent。@toolsoul: str, # SOUL.md 的完整内容description: str, # Agent 的一行描述创建流程从获取agent_name写入配置文件(包含 name 和 description)写入灵魂文件SOUL.md(定义 Agent 的人格和行为)更新中的错误回滚MCP(Model Context Protocol)是一种标准协议,允许 AI Agent 连接外部工具服务器。DeerFlow 通过。

weixin_43674738的博客 180

自定义注解方法建立参数解析器

以@CurrentUser注解为例,通过在Controller的方法参数上加入@CurrentUser 注解来注入当前登录用户对象。

Tiger_Paul的博客 893

银河麒麟硬盘健康检测:smartctl/badblocks实战与坏盘预判

xfs_repair检查。S.M.A.R.T检测。

信创运维工程师 · 银河麒麟 & 容器实战 | 金融生产环境迁移·等保加固 | 142篇原创·17万+阅读 859

SpringBoot用户鉴权以及统一获取用户信息

SpringBoot用户鉴权以及统一获取用户信息

weixin_37672801的博客 7886

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

springboot +vue实现token登录3之获取登录人员信息

1.通过自定义 @CurrentUser 获取当前登录用户 1、定义 @CurrenUser注解 package com.presoft.wydl.common.config; import java.lang.annotation.Retention; import java.lang.annotation.Target; import java.lang.annotation.Ret...

weixin_42199791的博客 1270

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

HandlerMethodArgumentResolver用于统一获取当前登录用户

为了将 HTTP 请求参数转换为 Java 对象,我们需要创建一个自定义的实现类。在这个类中,我们需要实现方法和方法。要在 Spring Boot 应用程序中使用自定义的实现类,我们需要将其注册到应用程序上下文中。为此,我们可以创建一个类,并实现接口。在这个类中,我们需要重写方法,并将自定义的实现类添加到参数解析器列表中。3.1 自定义权限拦截器自定义权限拦截器AuthenticationInterceptor,需实现HandlerInterceptor。

zzhongcy的专栏 1705

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

如何利用 HandlerMethodArgumentResolver 为每个请求注入当前用户?

Best Practice of avoiding the template code | 如何利用 HandlerMethodArgumentResolver 为每个请求注入当前用户?

斯人若彩虹 550

HandlerInterceptor+HandlerMethodArgumentResolver统一获取当前登录的用户

目录 一、最原始直接 二、AOP 三、拦截器+方法参数解析器 3.1 自定义权限拦截器 3.2 自定义参数注解 3.3 自定义方法参数解析器 3.4 配置MVC 环境:SpringBoot 2.0.4.RELEASE 需求:很多Controller方法,刚进来要先获取当前登录用户的信息,以便做后续的用户相关操作。 准备工作:前端每次请求都传token,后端封装一方法tokenUtils.getUserByToken(token),根据token解析得到currentUserInfo。...

qq_38178433的博客 1019

Spring MVC 驱动注册 HandlerMethodArgumentResolver接口应用example

从spring3.1 开始就有了这个接口,可以为@RequestMapping标注的方法扩展传入的参数 以shiro为例,扩展一个标注,@CurrentUser,只要有这个标注,就可以在shiro的安全上下文中取出适当的对象直接从参数传入,request响应函数。  import java.lang.annotation.Documented;   import java.lang

3097

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

1、使用到的两个枚举 ElementType枚举: TYPE //接口、类、枚举 .FIELD//字段、枚举的常量 METHOD//方法 PARAMETER//方法参数 CONSTRUCTOR //构造函数 LOCAL_VARIABLE//局部变量 ANNOTATION_TYPE//注解 PACKAGE///包 RetentionPolicy枚举 SOURCE //注解在源码是有效,将被编译器丢弃 CLASS //注解在编译时有效,但在运行时没有保留。这也...

Bruce_Json的博客 1292

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

自定义 @CurrenUser注解/

stanWang的博客 1万+

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.Retent...

小熙哥的博客 3910

SpringBoot拦截器中获取token中的用户信息并通过注解可以在任何一个Controller上获取到用户基本信息

首先创建一个CurrentUserMethodArgumentResolver类并实现HandlerMethodArgumentResolver 接口。 CurrentUserInfo.class 是封装的一个用户信息类,根据境况添加想获取的信息 CurrentUser.class是一个注解类,通过此注解可以获取当前用户的信息 package zut.edu.interceptor; import org.springframework.core.MethodParameter; import org.s

weixin_45102492的博客 6262

通过注解获取当前登录用户

1,自定义注解 @Target(ElementType.PARAMETER) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface CurrentUser { } 2.添加用户解析器 public class CurrentUserMethodArgumentResolver implements HandlerMethodArgumentResolver { @Override public boolean s

zeng772620023的博客 491

java 获取token_Web开发不得不知道的 token

1、什么是 token???Token 是服务端生成的一串字符串,以作客户端进行请求的一个令牌。2、token 做用户登录认证● 流程3、 Java 实现● 用户登录生成 token,保存到 Redis 中最简单的 token 可由 uid (用户唯一的身份标识)、sign (签名)、time (当前时间的时间戳) 加密组成。● 客户端把 token 信息存储到 cookie 中,发起购买请求① ...

weixin_39690391的博客 382

Springboot自定义参数注解,通过拦截器获取token用户数据,注入user实体到方法中

Springboot使用自定义参数注解获取token中用户数据,自定义参数解析HandlerMethodArgumentResolver

Lyndon的专栏 4988
上一篇: SpringBoot整合Druid配置数据源监控
下一篇: Spring缓存抽象
与黑夜为伍
博客等级 码龄7年 19粉丝 80原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值