【Java Web】检查用户登录状态,防止用户访问到非法页面

本文介绍了如何在SpringMVC应用中使用自定义注解@LoginRequired拦截请求,确保只有登录用户才能访问特定页面。通过HandlerInterceptor实现预处理逻辑,配置拦截器以排除静态资源。
摘要由CSDN通过智能技术生成
  • 使用拦截器
    • 在方法前标注自定义注解
    • 拦截所有请求,只处理带有该注解的方法
  • 自定义注解:
    • 常用元注解:@Target, @Rentention, @Document, @Inherited
    • 如何读取注解:
      - Method.getDeclaredAnnotations()
      - Method.getAnnotaion(Class<T> annotationClass)

业务场景:未登陆状态下,用户不能访问需要登陆才能访问的页面,例如修改个人信息页面等。

1. 自定义注解

package com.nowcoder.community.annotation;


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

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface LoginRequired {

}

2. 在方法前加上该注解

@LoginRequired
@RequestMapping(path = "/setting",method = RequestMethod.GET)
public String getSettingPage(){
    return "/site/setting";
}

3. 定义拦截器

package com.nowcoder.community.controller.Interceptor;


import com.nowcoder.community.annotation.LoginRequired;
import com.nowcoder.community.entity.User;
import com.nowcoder.community.util.HostHolder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Method;

@Component
public class LoginRequireInterception implements HandlerInterceptor {

    @Autowired
    private HostHolder hostHolder;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        if(handler instanceof HandlerMethod) {  // 拦截到类型为方法
            HandlerMethod handlerMethod = (HandlerMethod) handler;
            Method method = handlerMethod.getMethod();  // 获取方法
            LoginRequired loginRequired = method.getAnnotation(LoginRequired.class);  // 获取方法的注解
            if (loginRequired != null && hostHolder.getUser() == null) {  // 方法是loginRequired且user没登陆,需要拦截
                response.sendRedirect(request.getContextPath() + "/login");
                return false;
            }
        }

        return true;
    }
}

4. 配置拦截器

package com.nowcoder.community.config;

import com.nowcoder.community.controller.Interceptor.AlphaInterceptor;
import com.nowcoder.community.controller.Interceptor.LoginRequireInterception;
import com.nowcoder.community.controller.Interceptor.LoginTicketInterceptor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration

public class WebMvcConfig implements WebMvcConfigurer {

    @Autowired
    private AlphaInterceptor alphaInterceptor;

    @Autowired
    private LoginTicketInterceptor loginTicketInterceptor;

    @Autowired
    private LoginRequireInterception loginRequireInterception;

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        // 通过重写addInterceptors()方法,可以配置拦截器,对请求进行预处理或后处理。
        registry.addInterceptor(loginRequireInterception)
                .excludePathPatterns("/**/*.css", "/**/*.js", "/**/*.png", "/**/*.jpg", "/**/*.jpeg");

    }

}

Java中,实现这种功能通常涉及到Spring Security、Session管理和页面跳转。这里我会提供一个简化的示例,假设你已经设置了Spring Boot项目,并引入了Spring Security依赖。 首先,在`pom.xml`添加Spring Security依赖: ```xml <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> </dependency> </dependencies> ``` 然后,在`application.properties`配置文件里设置session超时时间和验证码相关属性: ```properties # 设置会话过期时间为两周 spring.session.timeout=1209600 # 验证码相关配置 spring.security.web.authentication.image-captcha.enabled=true captcha:location=classpath:/images/captchas/ ``` 接着,创建一个自定义的`AuthenticationEntryPoint`,用于处理授权访问: ```java @Component public class CustomAuthenticationEntryPoint implements AuthenticationEntryPoint { @Override public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException, ServletException { if (authException instanceof BadCredentialsException) { // 如果是非法登录尝试,显示验证码并跳转到登录界面 sendRedirect(request, response, "/login?showCaptcha=true"); } else { // 其他异常直接返回登录界面 sendRedirect(request, response, "/login"); } } private void sendRedirect(HttpServletRequest request, HttpServletResponse response, String location) throws IOException { response.sendRedirect(location); } } ``` 在`SecurityConfig.java`中配置Spring Security过滤器和验证码支持: ```java @Configuration @EnableWebSecurity public class SecurityConfig extends WebSecurityConfigurerAdapter { @Autowired public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception { // 添加其他身份验证逻辑... } @Bean public CustomAuthenticationEntryPoint authenticationEntryPoint() { return new CustomAuthenticationEntryPoint(); } // 其他必要的配置... } ``` 最后,在登录页面处理验证码和登录验证: ```java @Controller @RequestMapping("/login") public class LoginController { @GetMapping public String login(@RequestParam(required = false) Boolean showCaptcha, Model model) { // 显示登录表单,如果需要显示验证码,则传递标志给视图 if (showCaptcha != null && showCaptcha) { model.addAttribute("captcha", generateCaptchaImage()); } return "login"; } @PostMapping public String authenticate(@RequestParam String username, @RequestParam String password, @RequestParam String captcha, Model model) { // 这里检查用户名密码是否匹配以及验证码是否正确 // 如果验证成功,设置会话信息;失败则返回错误消息 } // 生成验证码图片的方法 private byte[] generateCaptchaImage() { // 使用Spring Security的CaptchaUtils生成图片 BufferedImage image = CaptchaGenerator.generateImage(); return ImageIO.toByteArray(image); } } ``` 这只是一个基本的框架,实际应用中可能还需要考虑更多细节,如持久化验证码、错误处理等。记住,为了保护隐私和安全,不要在生产环境中明文存储用户登录状态,而是应该使用加密的安全令牌(JWT或其他形式)。同时,为了提高用户体验,可以考虑使用第三方库如Apache Shiro来简化集成工作。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值