JavaWeb学习——登陆功能

目录

1.基础登陆功能

2.登陆校验 

3.登陆认证

3.1登陆校验--会话技术

3.2登陆校验--会话跟踪方案一

3.3登陆校验--登陆跟踪方案二、三

4.登陆校验

4.1JWT令牌--介绍

4.2JWT令牌--生成与校验

4.3JWT令牌--登录后下发令牌

4.4Filter--入门

4.5Fliter--详解(执行流程-拦截路径)

4.6Fliter--详解(过滤器链)

4.7Fliter--登陆校验过滤器

4.8Interceptor--入门

4.9Interceptor--详解

4.10Interceptor--登陆校验拦截器

4.11异常处理


1.基础登陆功能

 

2.登陆校验 

由于在没有进行登陆的情况下也可以进行部门管理员工管理的操作,所以需要进行登陆校验。


 

3.登陆认证

3.1登陆校验--会话技术

 会话技术是获取登陆标记的一种传统方式,用户登陆成功之后在每一次请求中,都会得到该标记。

        登录操作是一次请求响应,后面执行的操作也是请求响应,在后面的请求当中需要拿到当前登录的 数据,所以要在一次会话的多次请求之间来共享数据,也就是会话跟踪。

3.2登陆校验--会话跟踪方案一

        Cookie是客户端会话跟踪技术,储存在客户端浏览器。使用Cookie进行会话跟踪,可以在浏览器向服务器发起第一次请求时设置一个Cookie。比如在浏览器第一次请求登陆接口时,登陆接口执行完成之后就可以设置一个Cookie用于存储相关的信息如当前登陆用户的用户名及其信息,服务器向浏览器响应数据时,就将这个Cookie自动相应回去;浏览器接收到响应的数据时就会自动将数据储存在本地;在后续的请求当中浏览器会自动将数据携带到服务器端。自动进行的原因是因为Cookie是HTTP协议当中支持的技术,浏览器产商支持这一标准,HTTP协议当中就为此提供了一个响应头SetCookie以及一个请求头Cookie。

服务器端发送给浏览器的响应头用来设置Cookie,接收到的请求头用来接收浏览器端发送的请求携带存储的Cookie。

import com.study.pojo.Result;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;


/**
 * HttpSession演示
 */
@Slf4j
@RestController
public class SessionController {

    //设置Cookie
    @GetMapping("/c1")
    public Result cookie1(HttpServletResponse response){
        response.addCookie(new Cookie("login_username","itheima")); //设置Cookie/响应Cookie
        return Result.success();
    }

    //获取Cookie
    @GetMapping("/c2")
    public Result cookie2(HttpServletRequest request){
        Cookie[] cookies = request.getCookies();
        for (Cookie cookie : cookies) {
            if(cookie.getName().equals("login_username")){
                System.out.println("login_username: "+cookie.getValue()); //输出name为login_username的cookie
            }
        }
        return Result.success();
    }

}

跨域:在前后端分离的开发模式下,前端程序与后端程序独立部署,当前所处的位置以及请求的位置只要协议,IP地址,端口号任意一个不相同就是跨域,比如要访问前端页面执行登录操作就要访问另一个IP地址

3.3登陆校验--登陆跟踪方案二、三

        Seesion是存储在服务器端的会话技术 ,底层基于Cookie 。基于Session进行会话跟踪,在浏览器第一次进行请求的时候可以直接在服务器端获取会话对象Session,但是第一次请求时Session对象不存在,服务器会自动的创建一个会话对象Session,且每一个会话对象都有一个id(Session的id)。服务器端在给浏览器端响应数据的时候将Session的id通过Cookie响应给浏览器,也就是在响应头当中增加了一个SetCookie响应头,浏览器接收到响应数据之后会自动的将Cookie存储在浏览器本地。在后续的每一次请求当中都会将Cookie的数据获取出来并且携带到服务端。服务器端拿到Session的值也就是Session的id之后,就会从众多的Session当中找到当前请求对应的会话对象。这样就可以通过Session会话对象在同一次会话的多次请求之间来共享数据。

 令牌也就是用户身份的标识(字符串),浏览器发起请求请求登录接口的时候若登陆成功就生成一个令牌,在响应数据的时候就可以将这个身份响应给前端,前端接收到令牌之后可以将其保存起来,可以存在Cookie或其他的存储空间当中,在后续的每一次请求当中都需要将这个令牌携带到服务器端,校验令牌的有效性。如果是在同一个会话的多次请求当中共享数据,就可以将要共享的数据存在令牌当中。

4.登陆校验

4.1JWT令牌--介绍

        JWT令牌个人理解也就是将JSON的数据格式通过编码加密为字符串。Header部分以及PayLoad部分都是将JSON数据通过BASE64编码转化得来的,Signature部分是通过签名算法得来的。

         浏览器发起请求执行登录操作访问登陆的接口,登录成功生成一个JWT令牌。之后将生成的JWT令牌返回给前端,前端拿到JWT令牌之后就会自动存储起来,在后续的每一次请求当中都会将JWT令牌携带到服务器端,服务端就要进行统一拦截,先判断有没有将该令牌带过来,再判断令牌是否有效

4.2JWT令牌--生成与校验

要使用JWT令牌就要引入JWT依赖。

	/**
	 * 测试生成JWT令牌
	 */
	@Test
	public void testGenJWT() {
		Map<String, Object> claims = new HashMap<>();
		claims.put("id",1);
		claims.put("name","jane");

		String jwt = Jwts.builder()
				.signWith(SignatureAlgorithm.HS256, "rayjane")//签名算法
				.setClaims(claims)//自定义内容(载荷)
				.setExpiration(new Date(System.currentTimeMillis() + 3600 * 1000))//设置有效期为1h
				.compact();
		System.out.println(jwt);
	}

	/**
	 * 解析JWT
	 */
	@Test
	public void testParseJWT() {
		Claims claims = Jwts.parser()
				.setSigningKey("rayjane")
				.parseClaimsJws("eyJhbGciOiJIUzI1NiJ9.eyJuYW1lIjoiamFuZSIsImlkIjoxLCJleHAiOjE2OTMxNjI1Nzd9.4Az5KOYGuXxvVAL1EJ2l4fjw2VSyzCvkPhqPtAurvDM")
				.getBody();
		System.out.println(claims);
	}
4.3JWT令牌--登录后下发令牌

4.4Filter--入门

 

4.5Fliter--详解(执行流程-拦截路径)

4.6Fliter--详解(过滤器链)

 

 

4.7Fliter--登陆校验过滤器

 

import com.alibaba.fastjson.JSONObject;
import com.study.pojo.Result;
import com.study.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;

@Slf4j
@WebFilter(urlPatterns = "/*")
public class LoginCheckFilter implements Filter {

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest req = (HttpServletRequest) servletRequest;
        HttpServletResponse resp = (HttpServletResponse) servletResponse;

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

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

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

        //判断令牌是否存在,如果不存在,返回错误信息
        if(!StringUtils.hasLength(jwt)) {
            log.info("请求头中为空,返回未登录的信息");
            Result error = Result.error("NOT_LOGIN");
            //手动操作,对象转为JSON-->阿里巴巴fastjson
            String notLogin = JSONObject.toJSONString(error);
            resp.getWriter().write(notLogin);
            return;
        }

        //解析token,如果解析失败,返回错误信息
        try {
            JwtUtils.parseJWT(jwt);
        } catch (Exception e) {
            e.printStackTrace();
            log.info("解析令牌失败,返回未登录的信息");
            Result error = Result.error("NOT_LOGIN");
            //手动操作,对象转为JSON-->阿里巴巴fastjson
            String notLogin = JSONObject.toJSONString(error);
            resp.getWriter().write(notLogin);
            return;
        }

        //放行
        log.info("令牌合法,放行");
        filterChain.doFilter(servletRequest,servletResponse);
    }
}
4.8Interceptor--入门

 

4.9Interceptor--详解

4.10Interceptor--登陆校验拦截器

 

 

import com.alibaba.fastjson.JSONObject;
import com.study.pojo.Result;
import com.study.utils.JwtUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@Slf4j
@Component
public class LoginCheckInterceptor implements HandlerInterceptor {
    @Override //目标资源执行之前运行 ,返回true ,放行 ;false,不放行
    public boolean preHandle(HttpServletRequest req, HttpServletResponse resp, Object handler) throws Exception {
        //获取url
        String url = req.getRequestURL().toString();
        log.info("请求的url:{}",url);

        //判断url是否包含有login,如果包含说明是登录操作,放行
        if (url.contains("login")) {
            log.info("登陆操作,放行...");
            return true;
        }

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

        //判断令牌是否存在,如果不存在,返回错误信息
        if(!StringUtils.hasLength(jwt)) {
            log.info("请求头中为空,返回未登录的信息");
            Result error = Result.error("NOT_LOGIN");
            //手动操作,对象转为JSON-->阿里巴巴fastjson
            String notLogin = JSONObject.toJSONString(error);
            resp.getWriter().write(notLogin);
            return false;
        }

        //解析token,如果解析失败,返回错误信息
        try {
            JwtUtils.parseJWT(jwt);
        } catch (Exception e) {
            e.printStackTrace();
            log.info("解析令牌失败,返回未登录的信息");
            Result error = Result.error("NOT_LOGIN");
            //手动操作,对象转为JSON-->阿里巴巴fastjson
            String notLogin = JSONObject.toJSONString(error);
            resp.getWriter().write(notLogin);
            return false;
        }

        //放行
        log.info("令牌合法,放行");
        return true;
    }

    @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...");
    }
}
4.11异常处理

 

import com.study.pojo.Result;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

/**
 * 全局异常处理器
 */
@RestControllerAdvice
public class GlobalExceptionHandler {
    @ExceptionHandler(Exception.class)//处理所有异常
    public Result ex(Exception ex) {
        ex.printStackTrace();
        return Result.error("对不起,非法操作,请联系管理员!");
    }
}
  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Ustinian.488

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值