黑马程序员JavaWeb开发|案例:tlias智能学习辅助系统(5)登录认证

发布时间:2024年01月15日

?指路(1)(2)(3)(4)👇

黑马程序员JavaWeb开发|案例:tlias智能学习辅助系统(1)准备工作、部门管理_tlias智能学习辅助系统的需求分析-CSDN博客icon-default.png?t=N7T8https://blog.csdn.net/YOYU_/article/details/135476566黑马程序员JavaWeb开发|案例:tlias智能学习辅助系统(2)员工管理|分页查询、分页查询(带条件)-CSDN博客icon-default.png?t=N7T8https://blog.csdn.net/YOYU_/article/details/135491233黑马程序员JavaWeb开发|案例:tlias智能学习辅助系统(3)员工管理|新增员工、文件上传-CSDN博客icon-default.png?t=N7T8https://blog.csdn.net/YOYU_/article/details/135513546

黑马程序员JavaWeb开发|案例:tlias智能学习辅助系统(4)员工管理|修改员工、配置文件-CSDN博客icon-default.png?t=N7T8https://blog.csdn.net/YOYU_/article/details/135535512

一、登录功能

代码编写:

登录操作的核心逻辑就是按照用户名和密码查询数据库中的内容,如果有则登录成功,如果没有则返回错误信息。

结果展示:

前后端联调:

二、登录校验

1.会话技术

  • 会话:用户打开浏览器,访问web服务器的资源,会话建立,直到有一方断开连接,会话结束。在一次会话中可以包含多次请求和响应。
  • 会话跟踪:一种维护浏览器状态的方法,服务器需要识别多次请求是否来自于同一浏览器,以便在同一次会话的多次请求间共享数据
  • 会话跟踪方案:
  1. 客户端会话跟踪技术:Cookie

    1. HTTP - 标题 | Headers - 开发者手册 - 腾讯云开发者社区-腾讯云 (tencent.com)
    2. 核心:响应头(Set-Cookie: name=value)设置Cookie的数据,请求头(Cookie:name=value)用来携带Cookie的数据。
    3. 优点:HTTP协议中支持的技术
    4. 缺点:
      1. 移动端APP无法使用Cookie;
      2. 不安全,用户可以自己禁用Cookie;
      3. Cookie不能跨域。(跨域区分三个维度:协议、IP/域名、端口号)
  2. 服务端会话跟踪技术:Session

    1. 底层:基于Cookie实现的
    2. 响应头(Set-Cookie: JSESSIONID=1)设置Cookie的数据,请求头(Cookie:JSESSIONID=1)用来携带Cookie的数据。
    3. 优点:存储在服务器,安全
    4. 缺点:
      1. 服务器集群环境下无法直接使用Session;
      2. Cookie的缺点。
  3. 令牌技术

    1. 缺点:需要自己实现
    2. 优点:
      1. 支持PC端、移动端;
      2. 解决集群环境下的认证问题;
      3. 减轻服务器存储压力。

2.JWT令牌

JWT:JSON Web Token

定义了一种简洁、自包含的格式,用于在通信双方以json数据格式安全的传输信息。由于数字签名的存在,这些信息是可靠的。

JSON Web Tokens - jwt.io

Base64 编码/解码 | 菜鸟工具 (runoob.com)

JWT令牌生成

//    生成JWT
    @Test
    public void testGenJwt(){
        Map<String, Object> claims = new HashMap<>();
        claims.put("id", 1);
        claims.put("name", "tom");
        String jwt = Jwts.builder()
                .signWith(SignatureAlgorithm.HS256, "itheima")//签名算法
                .setClaims(claims)//自定义内容(载荷)
                .setExpiration(new Date(System.currentTimeMillis() + 3600 * 1000))//设置有效期为一个小时
                .compact();
        System.out.println(jwt);
    }

JWT令牌解析

//    解析JWT
    @Test
    public void testParseJwt(){
        Claims claim = Jwts.parser()
                .setSigningKey("itheima")//指定签名密钥
                .parseClaimsJws("eyJhbGciOiJIUzI1NiJ9.eyJuYW1lIjoidG9tIiwiaWQiOjEsImV4cCI6MTcwNTA3MjY3NH0.Yvw1YNjqip8ysiFnKavbaszCMo4zgqjFymwnK15nIJI")
                .getBody();//解析令牌
        System.out.println(claim);
    }
}

结果展示:

前后端联调:

F12抓取数据

前端在后续的每一次请求都会携带令牌到服务端

3.过滤器Filter

  • 概念:是JavaWeb三大组件(Servlet, Filter, Listener)之一;
  • 过滤器可以把对资源的请求拦截下来,从而实现一些特殊的功能;
  • 过滤器一般完成一些通用的操作,比如:登录校验、统一编码处理、敏感字符处理等。

Q:放行后访问对应资源,资源访问完成后,还会回到Filter中吗?会

? ? ? ?如果回到Filter中,是重新执行还是执行放行后的逻辑呢?执行放行后的逻辑

@ServletComponentScan:在启动类上增加该注解,引入Filter过滤器

代码展示:

package com.itheima.filter;

import com.alibaba.fastjson.JSONObject;
import com.github.pagehelper.BoundSqlInterceptor;
import com.github.pagehelper.util.StringUtil;
import com.itheima.pojo.Result;
import com.itheima.utils.JwtUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.StringUtils;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * ClassName: LoginCheckFilter
 * Package: com.itheima.filter
 */
@Slf4j
@WebFilter(urlPatterns = "/*")
public class LoginCheckFilter implements Filter {
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        //强转为http
        HttpServletRequest req = (HttpServletRequest) request;
        HttpServletResponse resp = (HttpServletResponse) response;

        //1.获取请求url
        String url = req.getRequestURL().toString();
        log.info("请求的url:{}", url);

        //2.判断请求url中是否包含login,如果包含,说明是登录操作,放行
        if (url.contains("login")){
            log.info("登录操作,放行……");
            chain.doFilter(request, response);
            return;
        }

        //3.获取请求头的令牌(token)
        String jwt = req.getHeader("token");

        //4.判断令牌是否存在,如果不存在,返回错误结果(未登录)
        if (!StringUtils.hasLength(jwt)){
            log.info("请求头token为空,返回未登录的信息");
            Result error = Result.error("NOT_LOGIN");
            //手动转换 对象--》json---》阿里巴巴fastJSON工具包
            String notlogin = JSONObject.toJSONString(error);
            resp.getWriter().write(notlogin);
            return;
        }

        //5.判断token,如果解析失败,返回错误结果(未登录)
        try {
            JwtUtils.parseJWT(jwt);
        } catch (Exception e) {//jwt令牌解析失败
            e.printStackTrace();
            log.info("解析令牌失败,返回未登录的错误信息");
            Result error = Result.error("NOT_LOGIN");
            //手动转换 对象--》json---》阿里巴巴fastJSON工具包
            String notlogin = JSONObject.toJSONString(error);
            resp.getWriter().write(notlogin);
            return;
        }

        //6.放行
        log.info("令牌合法,放行");
        chain.doFilter(request, response);

    }
}

拦截结果:

登录请求,直接放行

正确的jwt令牌,查询成功

错误的令牌,解析错误,返回json错误信息

4.拦截器Interceptor

  • 概念:是一种动态拦截方法调用的机制,类似于过滤器。Spring框架中提供的,用来动态拦截控制器方法的执行。
  • 作用:拦截请求,在指定的方法调用前后,根据业务需要执行预先设定的代码。

【Filter与Interceptor区别】

  • 接口规范不同:过滤器需要实现Filter接口,而拦截器需要实现HandlerInterceptor接口;
  • 拦截范围不同:过滤器Filter会拦截所有的资源,而Interceptor只会拦截Spring环境中的资源;
  • 放行代码不同:Filter需要用调用doFilter方法,Interceptor只需要return true。

退出登录之后,直接复制部门管理链接是无法进入的,拦截需要再次登录。

三、异常处理

@RestControllerAdvice:在全局异常处理器上加

@ExceptionHandler:指定当前方法要捕获的是哪一类型的异常

文章来源:https://blog.csdn.net/YOYU_/article/details/135539832
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。