JavaWeb-登录认证

1 登录校验:

2 会话技术:

  • 会话:浏览器访问资源,建立会话;一方断开连接,结束会话。一次会话可以包含多次请求和响应。
  • 会话跟踪:维护浏览器状态,服务器需要识别多次请求是否来自于同一个浏览器,以便在同一次会话的多次请求间共享数据
  • 会话跟踪方案:
    • 客户端会话跟踪技术:Cookie
      • 优点:HTTP协议自带且支持
      • 缺点:
        • 移动端APP无法使用
        • 不安全
        • 不能跨域
    • 服务端会话跟踪技术:Session(底层基于Cookie实现)
      • 优点:存储在服务端,安全
      • 缺点:
        • 服务器集群环境下无法使用
        • Cookie的缺点
    • 令牌技术(主流方案)
      • 优点:
        • 跨平台通用
        • 集群环境适用
        • 减轻服务器端存储压力
      • 缺点:
        • 需要自己实现

3 JWT令牌

JSON Web Token

组成:

  • 一:Header 头,记录令牌类型,签名算法。
  • 二:Payload 有效载荷,携带一些自定义消息、默认信息
  • 三:Signature 签名,防止Token被篡改、确保安全性。

场景:登录认证

  1. 登陆成功后,生成令牌
  2. 后续每个请求,都要携带JWT令牌,系统在每次请求处理之前,先校验令牌,通过后,在处理

生成:

引入依赖:

<!--JWT依赖-->
        <dependency>
            <groupId>io.jsonwebtoken</groupId>
            <artifactId>jjwt</artifactId>
            <version>0.9.1</version>
        </dependency>
        <!--JAVA8以后JWT需要:-->
        <dependency>
            <groupId>javax.xml.bind</groupId>
            <artifactId>jaxb-api</artifactId>
            <version>2.3.1</version>
        </dependency>
        <dependency>
            <groupId>org.glassfish.jaxb</groupId>
            <artifactId>jaxb-runtime</artifactId>
            <version>2.3.1</version>
        </dependency>

引入工具类

生成:

String jwtstr = Jwts.builder()
   .signWith(SignatureAlgorithm.HS256, "privatekey") // 签名算法、秘钥
   .setClaims(claims) // 自定义内容(载荷)Map或Claims
   .setExpiration(new Date(System.currentTimeMillis() + 3600 * 1000)) // 设置有效期为1h
   .compact();

校验

Claims claims = Jwts.parser()
       .setSigningKey("privatekey") //指定签名密钥,与生成时一致
       .parseClaimsJws("eyjhbGCiOjI1Ni9.eyJpZC6MSwiXhwiXjoxNjuSOtK1NTE3LCJ1c2VybmFtZSI6IlRvbSI9.EUFTeqPKGslekdBeczcWCe7a7xb
cllwB1MXllcTMwo") // 解析令牌
       .getBody();

校验报错则说明被篡改、失效

示例:

public class LoginController {
    @Autowired
    private EmpService empService;

    @PostMapping("/login")
    public Result login(@RequestBody Emp emp){
        log.info("员工登陆{}",emp);
        Emp e= empService.login(emp);

        if(e != null){
            Map<String, Object> claims =new HashMap<>();
            claims.put("id",e.getId());
            claims.put("name",e.getName());
            claims.put("username",e.getName());

            String jwt= JwtUtils.generateJwt(claims);
            return Result.success(jwt);
        }


        return Result.error("用户名或密码错误");
    }
}

4 过滤器Filter

注意在javax.servlet包下

概述:

  • JavaWeb三大组件(Servlet、Filter、Listener )之一
  • 可以拦截对资源的请求
  • 一般通用于:登录校验、统一编码处理、敏感字符处理…

使filter生效

  • 给filter加上 @WebFilter,实现Filter接口
  • 给启动类加上 @ServletComponentScan

执行流程:

  1. 浏览器请求进入Fliter,执行放行前逻辑
  2. 放行:chain.doFilter(request,response);进入对web资源的访问
  3. 回到Filter,执行放行后逻辑。

拦截路径:

@WebFilter(urlPatterns = "/*")
public class DemoFilter implements Filter {
    // Filter implementation
}
拦截路径urlPatterns值含义
拦截具体路径/login只有访问 /login 路径时,才会被拦截
目录拦截/emps/*访问 /emps 下的所有资源,都会被拦截
拦截所有/*访问所有资源,都会被拦截

过滤器链:

一个Web应用中可以配置多个过滤器,多个过滤器就形成了一个过滤器链。

过滤器执行顺序:按照类名字典序

登录校验Filter:

LoginFilter.java:

package org.example.ssmpratice1.filter;

import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.example.ssmpratice1.pojo.Result;
import org.example.ssmpratice1.utils.JwtUtils;

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

@Slf4j
@WebFilter(urlPatterns = "/*")//拦截所有请求
public class LoginFilter implements Filter {
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {

        //1.获取请求URL。
        HttpServletRequest httpServletRequest=(HttpServletRequest) servletRequest;
        String url = httpServletRequest.getRequestURL().toString();
        log.info("url:{}",url);


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


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


        //4.判断令牌是否存在,如果不存在,返回错误结果(未登录)。
        if (jwt==null || jwt==""){
            log.info("jwt为空,返回error");
            Result error=Result.error("NOT_LOGIN");
            //因为filter不是control,没有@RestController,所以将Result返回为JSON对象需要手动转换,此处使用fastJSON
            String notLogin= JSON.toJSONString(error);
            servletResponse.getWriter().write(notLogin);
            return;
        }


        //5.解析token,如果解析失败,返回错误结果(未登录)。
        try {
            JwtUtils.parseJWT(jwt);
        } catch (Exception e) {
            e.printStackTrace();
            log.info("解析令牌失败");
            Result error=Result.error("NOT_LOGIN");
            //因为filter不是control,没有@RestController,所以将Result返回为JSON对象需要手动转换,此处使用fastJSON
            String notLogin= JSON.toJSONString(error);
            servletResponse.getWriter().write(notLogin);
            return;
        }

        //6.放行。
        log.info("令牌合法,放行");
        filterChain.doFilter(servletRequest,servletResponse);

    }
}

5 拦截器Interceptor

概述:

由spring提供,动态拦截方法,类似于过滤器。

使用步骤:

1.定义拦截器,实现HandlerInterceptor接口,重写所有方法:

  • preHandle() 在目标资源方法执行前执行,返回true,放行;返回false,不放行
  • postHandle() 在目标资源方法执行后执行
  • afterCompletion() 视图渲染完毕后执行,最后执行

2.注册拦截器

拦截路径:

拦截器可以配置拦截哪些,不拦截哪些。

@Autowired
private LoginCheckInterceptor loginCheckInterceptor;

@Override
public void addInterceptors(InterceptorRegistry registry) {
    registry.addInterceptor( loginCheckInterceptor).addPathPatterns("/**").excludePathPatterns("/login");//拦截除/login外的所有访问
}

拦截路径含义举例
/ *一级路径能匹配 /depts,/emps,/login,不能匹配 /depts/1
/ **任意级路径能匹配 /depts,/depts/1,/depts/1/2
/depts/*/depts 下的一级路径能匹配 /depts/1,不能匹配 /depts/1/2,/depts
/depts/**/depts 下的任意级路径能匹配 /depts,/depts/1,/depts/1/2,不能匹配 /emps/1

执行流程:

请求先到过滤器Filter(如果有),再到拦截器Interceptor:

preHandle :判断是否放行:是->访问操作->postHandle->afterCompletion->回到filter(如果有)

二者比较:

  • 接口实现不同:
    • filter:Filter;
    • interceptor:HandlerIntercrptor
  • 拦截范围不同:
    • Filter:可以拦截所有资源
    • interceptor:只能拦截Spring环境中的资源
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇