springboot项目--实现登录(过滤器)与退出功能

1.分析

登录与退出功能是整个项目中最简单的功能,实现这两个功能,基本只要思路理好了,代码就随便写了,根据我的项目总结:

1.登录功能的思路基本如下:

①. 将页面提交的密码password进行md5加密处理, 得到加密后的字符串

②. 根据页面提交的用户名username查询数据库中员工数据信息

③. 如果没有查询到, 则返回登录失败结果

④. 密码比对,如果不一致, 则返回登录失败结果

⑥. 登录成功,将员工id存入Session, 并返回登录成功结果

2.登录过滤器的基本思路如下:

首先创建一个loginFilter类实现Filter接口,其次,我们实现doFilter方法,接下来就理清自己的思路:

A.获取本次请求的URI
B. 判断本次请求, 是否需要登录, 才可以访问
C. 如果不需要,则直接放行
D. 判断登录状态,如果已登录,则直接放行
E. 如果未登录, 则返回未登录结果

2.代码实现

1.登录功能代码实现

@PostMapping("/login")
    public R<Employee> login(HttpServletRequest request, @RequestBody Employee employee){

        //①. 将页面提交的密码password进行md5加密处理, 得到加密后的字符串
        String password = DigestUtils.md5DigestAsHex(employee.getPassword().getBytes());
        //②. 根据页面提交的用户名username查询数据库中员工数据信息
        LambdaQueryWrapper<Employee> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Employee::getUsername, employee.getUsername());
        Employee em = employeeService.getOne(queryWrapper);
        //③. 如果没有查询到, 则返回登录失败结果
        if(em == null){
            return R.error("登录失败");
        }
        //④. 密码比对,如果不一致, 则返回登录失败结果
        if(!password.equals(em.getPassword())){
            return R.error("登录失败");
        }
        //⑤. 查看员工状态,如果为已禁用状态,则返回员工已禁用结果
        if(em.getStatus() == 0){
            return R.error("该用户已被禁用");
        }
        //⑥. 登录成功,将员工id存入Session, 并返回登录成功结果
        request.getSession().setAttribute("employee",em.getId());
        return R.success(em);
    }


    /**
     * @ClassName EmployeeController
            * @Description :退出登录
            * @Return : com.itheima.reggie.common.R<java.lang.String>
            * @Author : xmc
            * @Date : 2022/5/21 14:09
    */
    @PostMapping("/logout")
    public R<String> logout(HttpServletRequest request){
        request.getSession().removeAttribute("employee");
        return R.success("退出成功");
    }

2.登录过滤器

@WebFilter(filterName = "loginCheckFilter", urlPatterns = "/*")
@Slf4j
public class LoginCheckFilter implements Filter {
    
    public static final AntPathMatcher PATH_MATCHER = new AntPathMatcher(); 
    
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {

        
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        HttpServletResponse response = (HttpServletResponse) servletResponse;

        //获取本次请求地址
        String requestURI = request.getRequestURI();
        log.info("拦截到路径{}",request);

        //配置不需要拦截的地址
        String[] url = new String[]{
                "/employee/login",
                "/employee/logout",
                "/backend/**",
                "/front/**"
        };
        //比较
        boolean check = this.check(url, requestURI);
        if(check){
            filterChain.doFilter(servletRequest,servletResponse);
            return;
        }
        if(request.getSession().getAttribute("employee") != null){
            filterChain.doFilter(servletRequest,servletResponse);
            return;
        }
        response.getWriter().write(JSON.toJSONString(R.error("NOTLOGIN")));
        return;
    }

    public boolean check(String[] urls,String requestURI){
        for (String url : urls) {
            if(PATH_MATCHER.match(url,requestURI)){
                return true;
            }
        }
        return false;
    }

3.总结

这里是简单的登录功能实现,思路理清是实现功能的前提!

好的,我可以为你提供关于 Spring Boot 使用 Token 实现登录验证和退出的方法。 1. 登录验证 在用户登录成功后,服务器端生成一个 Token,并将 Token 返回给客户端。客户端在之后的请求中携带 Token,服务器端通过解析 Token 来验证用户的身份。 具体实现如下: 1.1 在用户登录成功后,生成 Token 并将 Token 返回给客户端 可以使用 JWT(JSON Web Token)生成 Token。JWT 由三部分组成:Header、Payload 和 Signature。Header 和 Payload 中存储用户信息,Signature 用于验证 Token 的合法性。 生成 Token 的代码如下: ```java import io.jsonwebtoken.Jwts; import io.jsonwebtoken.SignatureAlgorithm; import java.util.Date; public class JwtUtils { private static final long EXPIRATION_TIME = 3600000; // Token 过期时间,这里设置为 1 小时 private static final String SECRET_KEY = "secret"; // 加密密钥,可以自定义 // 生成 Token public static String generateToken(String username) { Date now = new Date(); Date expiration = new Date(now.getTime() + EXPIRATION_TIME); String token = Jwts.builder() .setSubject(username) .setIssuedAt(now) .setExpiration(expiration) .signWith(SignatureAlgorithm.HS256, SECRET_KEY) .compact(); return token; } } ``` 1.2 在之后的请求中携带 Token 可以在请求的 Header 中添加 Authorization 字段,将 Token 的值设置为其 value。例如: ``` Authorization: Bearer eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJ1c2VybmFtZSIsImlhdCI6MTYyMDE4NzY5MywiZXhwIjoxNjIwMTkxMjkzfQ.GgO3x8D6R2pZahVn0v6zv9vKW9VlLDhUSJ5sCwGqjyQ ``` 1.3 在服务器端验证 Token 可以使用 Spring Security 的 JwtAuthenticationFilter 过滤器来验证 Token。JwtAuthenticationFilter 继承自 OncePerRequestFilter,每个请求只会被该过滤器执行一次。 ```java import io.jsonwebtoken.Claims; import io.jsonwebtoken.Jwts; import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.core.Authentication; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.web.authentication.www.BasicAuthenticationFilter; import org.springframework.util.StringUtils; import javax.servlet.FilterChain; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; public class JwtAuthenticationFilter extends BasicAuthenticationFilter { private static final String HEADER_AUTHORIZATION = "Authorization"; private static final String TOKEN_PREFIX = "Bearer "; private static final String SECRET_KEY = "secret"; // 加密密钥,需要与生成 Token 的密钥一致 public JwtAuthenticationFilter(AuthenticationManager authenticationManager) { super(authenticationManager); } @Override protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException { String authorizationHeader = request.getHeader(HEADER_AUTHORIZATION); if (StringUtils.hasText(authorizationHeader) && authorizationHeader.startsWith(TOKEN_PREFIX)) { String token = authorizationHeader.substring(TOKEN_PREFIX.length()); try { Claims claims = Jwts.parser() .setSigningKey(SECRET_KEY) .parseClaimsJws(token) .getBody(); String username = claims.getSubject(); Authentication authentication = new UsernamePasswordAuthenticationToken(username, null, null); SecurityContextHolder.getContext().setAuthentication(authentication); } catch (Exception e) { // Token 验证失败,可以根据具体情况进行处理 } } chain.doFilter(request, response); } } ``` 2. 退出登录 在用户退出登录时,服务器端需要删除 Token。 具体实现如下: ```java import io.jsonwebtoken.Claims; import io.jsonwebtoken.Jwts; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.util.StringUtils; import javax.servlet.http.HttpServletRequest; public class JwtUtils { private static final String HEADER_AUTHORIZATION = "Authorization"; private static final String TOKEN_PREFIX = "Bearer "; private static final String SECRET_KEY = "secret"; // 加密密钥,需要与生成 Token 的密钥一致 // 获取当前用户的用户名 public static String getCurrentUsername() { return SecurityContextHolder.getContext().getAuthentication().getName(); } // 从请求中获取 Token public static String getTokenFromRequest(HttpServletRequest request) { String authorizationHeader = request.getHeader(HEADER_AUTHORIZATION); if (StringUtils.hasText(authorizationHeader) && authorizationHeader.startsWith(TOKEN_PREFIX)) { return authorizationHeader.substring(TOKEN_PREFIX.length()); } return null; } // 验证 Token 是否有效 public static boolean validateToken(String token) { try { Jwts.parser() .setSigningKey(SECRET_KEY) .parseClaimsJws(token); return true; } catch (Exception e) { return false; } } // 删除 Token public static void deleteToken(String token) { // 可以将 Token 存储到数据库或 Redis 中,然后在这里进行删除 } } ``` 在用户退出登录时,调用 deleteToken 方法即可删除 Token。 希望这些信息对你有所帮助,如果还有其他问题,欢迎随时提出。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值