Login verification using Java

conversational technology

        Session: The user opens the browser, accesses the resources of the web server, and the session is established until one party disconnects and the session ends. A session can contain multiple requests and responses.

        Session tracking: A method of maintaining browser state where the server needs to identify whether multiple requests are from the same browser in order to share data between multiple requests in the same session.

        Session tracking solution:

                Client session tracking technology: Cookies

                Server-side session tracking technology: Session

                Token technology

Session tracking solution comparison:

        Cookies - Advantages: Technologies supported in the HTTP protocol

Disadvantages: Mobile APP cannot use cookies

          Not safe, users can disable cookies themselves

          Cookies cannot cross domains

        Session-Advantages: stored on the server side, safe

        Disadvantages: Session cannot be used directly in a server cluster environment

                   Disadvantages of Cookies

        Advantages: Support PC and mobile terminals

                   Solving authentication issues in cluster environments

                   Reduce server-side storage pressure

           Disadvantages: Need to implement it yourself

JWT token

        Full name: JSON Web Token

        Defines a concise, self-contained format for securely transmitting information in json data format between communicating parties. This information is reliable due to the presence of digital signatures.

        composition:

                The first part: Header (header), recording token type, signature algorithm, etc.

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

                The second part: Payload (payload), carries some custom information, default information, etc.

                                例如:{"id":"1","usename":"Tom"}

                The third part: Signature (signature), prevents Token from being tampered with and ensures security.

                                Add the header and payload to the specified key and calculate it through the specified signature algorithm.

JWT

        Scenario: Login authentication

                1. After successful login, generate a token

                2. Each subsequent request must carry a JWT token. The system will verify the token before processing each request, and then process it after verification.

Introduce dependencies into pom.xml:

 <dependency>
            <groupId>io.jsonwebtoken</groupId>
            <artifactId>jjwt</artifactId>
            <version>0.9.1</version>
        </dependency>
    @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, "itbignyi")
                .setClaims(claims)
                .setExpiration(new Date(System.currentTimeMillis() + 3600 * 1000))
                .compact();
        System.out.println(jwt);
@Test
    public void testParseJwt() {
        Claims claims = Jwts.parser()
                .setSigningKey("itbignyi")
                .parseClaimsJws("eyJhbGciOiJIUzI1NiJ9.eyJuYW1lIjoidG9tIiwiaWQiOjEsImV4cCI6MTY5NDUzMjAwOH0.D4TjgQSvqZJlUNioEKxUn8euvxu9gqnSo4jfsJGuL7Q")
                .getBody();
        System.out.println(claims);

Note: The signing key used for JWT verification must match the key used for generating the JWT token.

                If an error occurs when parsing and verifying the JWT token, it means that the JWT token has been tampered with or invalid, and the token is illegal.

Write the code:

FilterFilter

Concept: Filter filter is one of the three major components of JavaWeb (Servlet, Filter, Listener)

Filters can intercept requests for resources to achieve some special functions.

Filters generally complete some common operations, such as: login verification, unified encoding processing, processing of sensitive characters, etc.

Define Filter: define a class, implement the Filter interface, and override all its methods

Configure Filter: Add the @WebFilter annotation to the Filter class, configure the path to intercept resources, and add @ServletComponerntScan to the boot class to enable Servlet component support.

package com.itheima.filter;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import java.io.IOException;

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

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        Filter.super.init(filterConfig);
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        filterChain.doFilter(servletRequest, servletResponse);
    }

    @Override
    public void destroy() {
        Filter.super.destroy();
    }
}

 Filter interception path:

        Filter can configure different interception resource paths according to needs:

Filter chain:

        Introduction: In a web application, multiple filters can be configured, and these multiple filters form a filter chain.

        Order: Annotate the configured Filter, the priority is based on the natural ordering of the filter class name (string)

 Login verification

        Login Verification Filter-Process:

1. Get the request URL 
 2. Determine whether the request URL contains login. If it does, indicate the login operation and allow it. 3. 
 Get the token in the request header 
 . 4. Determine whether the token exists. If it does not exist, return an error result. (Not logged in) 
 5. Parse the token. If the parsing fails, return an error result (Not logged in) 
 6. Release

package com.itheima.filter;

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

import javax.imageio.spi.ServiceRegistry;
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 res = (HttpServletResponse) servletResponse;
//         1.获取请求url
        String url = req.getRequestURI().toString();
        log.info("请求的url:{}", url);
//         2.判断请求url中是否包含login,如果包含,说明登录操作,放行
        if (url.contains("login")) {
            log.info("登录操作,放行...");
            filterChain.doFilter(servletRequest,servletResponse);
            return;
        }
//         3.获取请求头中的令牌(token)
        String jwt = req.getHeader("token");
//         4.判断令牌是否存在,如果不存在,返回错误结果(未登录)
        if (!StringUtils.hasLength(jwt)) {
            log.info("请求头token,为空,返回未登录的信息");
            Result error = Result.error("NOT_LOGIN");
            String notLogin = JSONObject.toJSONString(error);
            res.getWriter().write(notLogin);
            return;
        }
//         5.解析token,如果解析失败,返回错误结果(未登录)
        try {
            JwtUtils.pareJWT(jwt);
        } catch (Exception e) {
            e.printStackTrace();
            log.info("解析失败");
            Result error = Result.error("NOT_LOGIN");
            String notLogin = JSONObject.toJSONString(error);
            res.getWriter().write(notLogin);
            return;
        }
//         6.放行
        log.info("合法放行");
        filterChain.doFilter(servletRequest, servletResponse);


    }
}

Interceptor

Overview: It is a mechanism for dynamically intercepting method calls, similar to a filter. Provided by the Spring framework to dynamically intercept the execution of controller methods.

Function: intercept requests, execute preset code according to business needs before and after calling the specified method

Getting Started with Interceptor

1. Define the interceptor, implement the HandlerInterceptor interface, and rewrite all its methods

2. Register interceptor

package com.itheima.config;

import com.itheima.interceptor.LoginCheckInterceptor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration  //配置类
public class WebConfig implements WebMvcConfigurer {
    @Autowired
    private LoginCheckInterceptor loginCheckInterceptor;

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(loginCheckInterceptor).addPathPatterns("/**");

    }

}
package com.itheima.interceptor;

import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@Component
public class LoginCheckInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        return HandlerInterceptor.super.preHandle(request, response, handler);
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        HandlerInterceptor.super.postHandle(request, response, handler, modelAndView);
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        HandlerInterceptor.super.afterCompletion(request, response, handler, ex);
    }
}

Interceptor - interception path

        The interceptor can configure different interception paths according to needs.

Interceptor-execution process

 Filter and Interceptor

The interface scope is different: the filter needs to implement the Filter interface, and the interceptor needs to implement the HandlerInterceptor interface

The interception scope is different: Filter will intercept all resources, while Interceptor will only intercept resources in the Spring environment. 

 Run the code:

package com.itheima.interceptor;

import com.alibaba.fastjson.JSONObject;
import com.itheima.pojo.Result;
import com.itheima.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
    public boolean preHandle(HttpServletRequest req, HttpServletResponse res, Object handler) throws Exception {


//         1.获取请求url
        String url = req.getRequestURI().toString();
        log.info("请求的url:{}", url);
//         2.判断请求url中是否包含login,如果包含,说明登录操作,放行
        if (url.contains("login")) {
            log.info("登录操作,放行...");
            return true;
        }
//         3.获取请求头中的令牌(token)
        String jwt = req.getHeader("token");
//         4.判断令牌是否存在,如果不存在,返回错误结果(未登录)
        if (!StringUtils.hasLength(jwt)) {
            log.info("请求头token,为空,返回未登录的信息");
            Result error = Result.error("NOT_LOGIN");
            String notLogin = JSONObject.toJSONString(error);
            res.getWriter().write(notLogin);
            return false;
        }
//         5.解析token,如果解析失败,返回错误结果(未登录)
        try {
            JwtUtils.pareJWT(jwt);
        } catch (Exception e) {
            e.printStackTrace();
            log.info("解析失败");
            Result error = Result.error("NOT_LOGIN");
            String notLogin = JSONObject.toJSONString(error);
            res.getWriter().write(notLogin);
            return false;
        }
//         6.放行
        log.info("合法放行");
        return true;




    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
    }
}

Exception handling

Global exception handler

package com.itheima.exception;

import com.itheima.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("操作失败,联系管理员");
    }
}

Guess you like

Origin blog.csdn.net/jbykmzls/article/details/132838933