登陆校验功能实现

  1. 登录校验的实现思路是怎样的?

    登陆过程实现思路:Controller层负责接收前端的请求,调用service层负责逻辑处理,再调用mapper层来对数据进行增删改查,将数据逐级传递给前端。

    public class LoginController {
        @Autowired
        private EmpService empService;
    ​
        // 负责前端的请求和响应
        @PostMapping("/login")
        public Result login(@RequestBody Emp emp) {
            // 调用Service层完成逻辑
            Emp loginEmp = empService.login(emp);
            // 返回统一响应结果给前端
            returun loginEmp == null? Result.error("账号或密码失败"):Result.success();
    // service层实现逻辑
    @Override
        public Emp login(Emp emp) {
            return empMapper.getByUsernameAndPassword(emp);
        }
    // mapper层根据用户名密码查找用户
    @Select("select * from emp where username = #{username} and password = #{password} ;")
        Emp getByUsernameAndPassword(Emp emp);
     
  2. 会话技术有哪些方式可以实现?

    有两种方式可以实现会话技术

    方式1:使用Cookie(客户端会话跟踪技术)和Session(服务端会话跟踪技术)

    方式2:使用JWT令牌技术

  3. JWT令牌组成部分有哪些,各自作用是什么? JWT令牌由HeaderPayloadSignature三部分组成,每部分中间使用点(.)分隔,比如:xxxxx.yyyyy.zzzzz 第一部分:Header(头),作用:记录令牌类型、签名算法等。

    {
        "alg":"HS256",
        "type":"JWT"
    } 

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

    {
        "id":"1",
        "username":"Tom"
    }

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

    HMACSHA256(
        base64UrlEncode(header) + "." +
        base64UrlEncode(payload),
        secret
    )

  4. 怎么使用JWT令牌?(依赖,创建,校验)

     

    // 在pom.xml文件中导入依赖
    <dependency>
        <groupId>io.jsonwebtoken</groupId>
        <artifactId>jjwt</artifactId>
        <version>0.9.1</version>
    </dependency>
    // 创建JWT对象
    public class JwtDemo {
    ​
        @Test
        public void genJwt(){
            Map<String,Object> claims = new HashMap<>();
            claims.put("id",1);
            claims.put("username","Tom");
    ​
            String jwt = Jwts.builder()
                    .setClaims(claims) //执行第二部分负载, 存储的数据
                    .signWith(SignatureAlgorithm.HS256, "itheima") //签名算法及秘钥
                    .setExpiration(new Date(System.currentTimeMillis() + 12*3600*1000)) //设置令牌的有效期
                    .compact();
            System.out.println(jwt);
        }
    ​
    }
    // 校验
     public void parseJwt(){
            Claims claims = Jwts.parser()
                    .setSigningKey("itheima")
                                .parseClaimsJws("eyJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjU5OTk1NTE3LCJ1c2VybmFtZSI6IlRvbSJ9.EUTfeqPkGslekdKBezcWCe7a7xbcIIwB1MXlIccTMwo")
                    .getBody();
            System.out.println(claims);
        }

  5. 项目中在什么时候去生成令牌? 一般都是在登陆过程中去生成令牌,登陆之前不能生成令牌。

  6. 当前端携带令牌访问资源时怎么去拦截校验令牌的合法性?

    当令牌的时效性过期时,可以使用过滤器和拦截器进行拦截

  7. 过滤器具体使用的步骤是怎样的?

     

    // 首先要获取请求路径
    HttpServletRequest servlet = (HttpServletRequest) servletRequest;
     String url = servlet.getRequestURL().toString();
    // 判断请求路径是否是登陆(如果是登陆操作,那就直接放行)
    if (url.contains("login")) {
                // 登录,直接放行
                filterChain.doFilter(servletRequest,servletResponse);
                return;
            }
    // 不是登陆操作就获取请求头
     String jwt = servlet.getHeader("token");
    // 判断请求头是否存在,如果请求头是空的就得拦截
    if (jwt == null) {
                notLoginResponse(servletResponse);
                // 拦截
                return;
            }
    // 如果请求头不是空的就开始解析,解析成功就放行,解析失败就返回到未登陆的界面。
    try {
                Claims claims = JwtUtils.parseJWT(jwt);
                // 放行
                filterChain.doFilter(servletRequest,servletResponse);
            } catch (Exception e) {
                e.printStackTrace();
                // 令牌失效
                notLoginResponse(servletResponse);
            }

  8. 拦截器具体使用的步骤是怎样的?

    拦截器的具体实现步骤和过滤器类似

    // 首先获取请求路径
    String url = request.getRequestURL().toString();
    // 判断是否登陆请求(如果是登陆操作直接放行)
    if (url.contains("login")) {
        // 登录,直接放行
        return true;
        }
    // 获取请求头
    String jwt = request.getHeader("token");
    // 判断请求头是否为空
    if (jwt == null) {
                notLoginResponse(response);
                // 拦截
                return false;
            }
    // 请求头不为空就开始解析令牌,解析成功就放行,解析失败就返回到未登陆的界面。
     try {
                Claims claims = JwtUtils.parseJWT(jwt);
                // 放行
                return true;
            } catch (Exception e) {
                e.printStackTrace();
                // 令牌失效
                notLoginResponse(response);
                return false;
            }
    // 其中的notLoginResponse方法是返回失败的结果给前端
    private void notLoginResponse(ServletResponse servletResponse) throws IOException {
            // 返回统一NOT_LOGIN结果给前端
            Result errResult = Result.error("NOT_LOGIN");
            // 把errResult对象转换成JSON字符串
            ObjectMapper objectMapper = new ObjectMapper();
            String json = objectMapper.writeValueAsString(errResult);
            // 返回到前端
            servletResponse.getWriter().write(json);
        }

  9. 项目中异常是怎么处理的?具体怎么实现?

    方式1:在Controller的方法中进行try...catch处理(不建议使用,代码太过臃肿)

    方式2:全局处理异常,具体实现步骤,在exception包中创建一个全局异常处理类来进行管理

    使用全局异常处理效果展示:

     

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值