SpringBoot案例3 登录校验

1.登录校验的实现思路是怎样的?
在员工登录成功后,需要将用户登录成功的信息,存起来,记录用户已经登录成功的标记。
在浏览器发起请求时,需要在服务端进行统一拦截,然后读取登录标记中的信息,如果有登录成功的信息,就说明用户登录成功,放行请求,如果发现登录标记中没有登录成功的标记,则给前端返回错误信息,跳转至登录页面。
2.会话技术有哪些方式可以实现?
客户端会话跟踪技术:Cookie

服务端会话跟踪技术:Session

传统技术可以使用Cookie+Session去实现会话,进行会话跟踪。但是这种传统方式有弊端:不能在集群服务中灵活使用,手机客户端无法支持Cookie。
为了解决这些问题,可以使用令牌技术来解决。令牌技术优点是:解决了传统方式Cookie+Session的弊端

3.JWT令牌组成部分有哪些,各自作用是什么?
JWT令牌由Header、Payload、Signature三部分组成

Header(头),作用:记录令牌类型、签名算法等。

Payload(有效载荷),作用:携带一些用户信息及过期时间等。

Signature(签名),作用:防止Token被篡改、确保安全性。

4.怎么使用JWT令牌?(依赖,创建,校验)
(1) 依赖
<dependency>
    <groupId>io.jsonwebtoken</groupId>
    <artifactId>jjwt</artifactId>
    <version>0.9.1</version>
</dependency>
 (2) 创建
public void createJwt() {
//        定义令牌要携带的数据
        Map<String, Object> claims = new HashMap<>();
        claims.put("id", 666);
        claims.put("username", "wise");
        claims.put("password", "123");
 
        String jwt = Jwts.builder()
                .setClaims(claims)
//                设置加密算法及签名秘钥
                .signWith(SignatureAlgorithm.HS256, "wise233")
//                设置过期时间
                .setExpiration(new Date(System.currentTimeMillis() + 60 * 1000))
                .compact();
 
        System.out.println("jwt = " + jwt);
 
    }
(3) 校检
 public void parseJwt() {
//        这里填上面代码生成的令牌
        String jwt = "eyJhbGciOiJIUzI1NiJ9.eyJwYXNzd29yZCI6IjEyMyIsImlkIjo2NjYsImV4cCI6MTY5MTIwNjY4MiwidXNlcm5hbWUiOiJ3aXNlIn0.BsB9pZJi8Q5I4z16S9HA3KnZa985WYGkL1gyAt3Tbac";
 
//        解析
        Claims claims = Jwts.parser()
//                设置签名秘钥
                .setSigningKey("wise233")
//                jwt令牌
                .parseClaimsJws(jwt)
//                获取令牌中携带的数据
                .getBody();
 
//        如果令牌失效,解析会抛异常,注:令牌过期也会报错
//        如果没有抛出异常,正常解析,则说明令牌有效
 
        System.out.println("claims = " + claims);
        System.out.println("username : " + claims.get("username"));
 
    }
5.项目中在什么时候去生成令牌?
登录成功之后,生成JWT令牌并返回给浏览器。

6.当前端携带令牌访问资源时怎么去拦截校验令牌的合法性?
登录完成后,会把JWT令牌返回给前端,前端浏览器会将其存入本地存储。 在后面的请求中,前端会自动在请求头中将令牌token携带到服务端

校验流程:

获取请求url。
判断请求url中是否包含login,如果包含,说明是登录操作,放行。
获取请求头中的令牌(token)。
判断令牌是否存在,如果不存在,返回错误结果(未登录)。
解析token,如果解析失败,返回错误结果(未登录)。
放行。
7.过滤器具体使用的步骤是怎样的?
(1) 定义类,实现 Filter接口,并重写doFilter方法
public class DemoFilter implements Filter {
    /**
     * @param servletRequest 负责处理客户端发送过来的请求(获取参数)
     * @param servletResponse 负责服务端响应数据给客户端
     * @param filterChain 过滤链,实现是否进行拦截(截停,放行)
     * @throws IOException
     * @throws ServletException
     */
    @Override
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
 
    }
}
(2) 配置Filter拦截资源的路径:在类上定义@WebFilter注解
拦截路径

urlPattern值

含义

拦截具体路径

/login

只有访问 /login 路径时,才会被拦截

目录拦截

/emps/*

访问/emps下的所有资源,都会被拦截

拦截所有

/*

访问所有资源,都会被拦截

//把注解注释掉,就不会实现过滤了,因为被注解后就是一个普通的类
@WebFilter(urlPatterns = "/*")
public class DemoFilter implements Filter {
    @Override
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
 
    }
}
(3) 在doFilter方法中输出一句话,并放行
@WebFilter(urlPatterns = "/*")
public class DemoFilter implements Filter {
    @Override
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
        System.out.println("我是过滤器,嘻嘻,你被捕了~");
        
        //放行
        chain.doFilter(req, res);
 
    }
}
(4) 在引导类上使用@ServletComponentScan注解开启 Servlet  组件扫描
@ServletComponentScan//开启 Servlet组件扫描
@SpringBootApplication
public class TliasWebManagementApplication {
 
    public static void main(String[] args) {
        SpringApplication.run(TliasWebManagementApplication.class, args);
    }
 
}
8.拦截器具体使用的步骤是怎样的?
(1) 定义拦截器
实现HandlerInterceptor接口,并重写其所有方法。

@Component
public class LoginCheckInterceptor implements HandlerInterceptor {
    //目标资源方法执行前执行 , true : 放行 ; false : 不放行,拦截 ;
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("我是拦截器,你被逮捕了,美丽的小姐~");
        //如果校验通过放行
        return false;
    }
 
 
    //目标资源方法执行后执行
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println("postHandle ....");
    }
    
     //请求处理完成后调用
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.out.println("afterCompletion ....");
    }
 
}
(2) 注册拦截器
实现WebMvcConfigurer接口,并重写其addInterceptors方法。

记得加上注解@Configuration,用于标识这个类是配置类。

拦截路径

urlPattern值

含义

拦截具体路径

/login

只有访问 /login 路径时,才会被拦截

目录拦截

/emps/*

访问/emps下的下一级资源,如: /emps/1 ,但是 不会拦截 /emps/list/1,/emps/list/1/2

目录拦截

/emps/**

访问/emps下的所有资源,都会被拦截

拦截所有

/**

访问所有资源,都会被拦截

@Configuration
public class WebConfig implements WebMvcConfigurer {
    @Autowired
    private LoginCheckInterceptor loginCheckInterceptor;
 
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(loginCheckInterceptor).addPathPatterns("/**");
    }
}
9.过滤器和拦截器的区别

接口规范不同:过滤器需要实现Filter接口,而拦截器需要实现HandlerInterceptor接口。
拦截范围不同:过滤器Filter会拦截所有的资源,而Interceptor只会拦截Spring环境中的资源。
10.项目中异常是怎么处理的?具体怎么实现?
使用全局异常处理器处理

SpringMVC中提供了全局异常处理器接收所有Controller中产生的异常。一般定义在exception包下

具体实现

@RestControllerAdvice
public class GlobalExceptionHandler {
 
    /**
     * Exception异常分类
     *  - 运行时异常 : RuntimeException , 编译时无需处理 .
     *  - 编译时异常 : 非 RuntimeException , 编译时处理 .
     */
    @ExceptionHandler(Exception.class)
    public Result ex(Exception ex){
        ex.printStackTrace();
        return Result.error("系统繁忙, 请稍后重试 ... ");
    }
 
}
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值