从spring boot到spring cloud(七)整合JWT(Json Web Token)实现认证实例

最开始未分前后端分离的时候,用户权限是通过session保存的。前后端分离以后需要一个媒介来标识用户状态,就产生了token。JWT技术主要封装了用于用户登录鉴权的基本功能

session认证

Session:在计算机中,尤其是在网络应用中,称为“会话控制”。Session对象存储特定用户会话所需的属性及配置信息。这样,当用户在应用程序的Web页之间跳转时,存储在Session对象中的变量将不会丢失,而是在整个用户会话中一直存在下去。当用户请求来自应用程序的 Web页时,如果该用户还没有会话,则Web服务器将自动创建一个 Session对象。当会话过期或被放弃后,服务器将终止该会话。Session 对象最常见的一个用法就是存储用户的首选项。例如,如果用户指明不喜欢查看图形,就可以将该信息存储在Session对象中。有关使用Session 对象的详细信息,请参阅“ASP应用程序”部分的“管理会话”。注意会话状态仅在支持cookie的浏览器中保留。

token认证

Token在计算机身份认证中是令牌(临时)的意思,在词法分析中是标记的意思。一般作为邀请、登录系统使用。

如果非分布式一般保存在本地全局变量集合中,或者保存到redis中。分布式的话就只能保存到redis,否则其他服务无法获取。

什么是JWT

JWT(全称:Json Web Token)是一个开放标准(RFC 7519),它定义了一种紧凑的、自包含的方式,用于作为JSON对象在各方之间安全地传输信息。该信息可以被验证和信任,因为它是数字签名的。

JWT由3部分组成:标头(Header)、有效载荷(Payload)和签名(Signature)

eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIxIiwiZXhwIjoxNjUzODA5MTc3fQ.WZr_z0XCZdm_G9oc_HD-YT2xF0dKyy8257T_2Tk4130


eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.            //标头(Header)
eyJzdWIiOiIxIiwiZXhwIjoxNjUzODA5MTc3fQ.          //有效载荷(Payload)
WZr_z0XCZdm_G9oc_HD-YT2xF0dKyy8257T_2Tk4130      //签名(Signature)

Base64(Header).Base64(Payload).HMACSHA256(base64UrlEncode(header)+"."+base64UrlEncode(payload),secret)

有效载荷(Payload)  一般可以存储用户基本信息用于业务操作。

搭建springboot

从spring boot到spring cloud(二)JAVA入门教学,搭建基本的springboot_lzy711的博客-CSDN博客

可以查看过去的文章。

maven文件



	4.0.0
	
		org.springframework.boot
		spring-boot-starter-parent
		2.5.7
		 
	
	com.aqjyxt
	aqjyxt
	0.0.1-SNAPSHOT
	aqjyxt
	Demo project for Spring Boot
	
		1.8
	
	
		
			org.springframework.boot
			spring-boot-starter-web
		
		
			com.alibaba
			druid-spring-boot-starter
			1.1.10
		
		
			org.mybatis.spring.boot
			mybatis-spring-boot-starter
			2.2.2
		
		
            org.springframework.boot
            spring-boot-starter-web
        
		
            org.springframework.boot
            spring-boot-starter-web
        
        
            io.springfox
            springfox-boot-starter
            3.0.0
    	
    	
            com.github.xiaoymin
            swagger-bootstrap-ui
            1.9.6
        
		
			mysql
			mysql-connector-java
			runtime
		
		
			org.springframework.boot
			spring-boot-starter-test
			test
		
		
            com.auth0
            java-jwt
            3.4.0
        
	

	
		
			
				org.springframework.boot
				spring-boot-maven-plugin
			
		
	


主要是导入JWT

        
            com.auth0
            java-jwt
            3.4.0
       

编写JWT工具类

package com.aqjyxt.bean;

import com.alibaba.druid.util.StringUtils;
import com.aqjyxt.entity.aqjyxt_user;
import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTCreator;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.interfaces.DecodedJWT;

import java.util.Calendar;

import javax.xml.bind.DatatypeConverter;

/**
 * @author admin
 */
public class JWTUtils {

    //解析token的秘钥
	public static String password = "admin123";
    /**
     * 获取token
     * @param u user
     * @return token
     */
    public static String getToken(aqjyxt_user u) {
        Calendar instance = Calendar.getInstance();
        //默认令牌过期时间7天
        instance.add(Calendar.DATE, 7);

        //把用户id保存到subject变量,也可以使用.withClaim("userId", 123)
        JWTCreator.Builder builder = JWT.create();
        builder.withSubject(u.getId());

        return builder.withExpiresAt(instance.getTime())
                .sign(Algorithm.HMAC256(password));
    }

    /**
     * 验证token合法性 成功返回token
     */
    public static DecodedJWT verify(String token){
    	return JWT.require(Algorithm.HMAC256(password)).build().verify(token);
    }
    
	/**
	 * 解析Jwt字符串
	 *
	 * @param jwt Jwt字符串
	 * @return Claims 解析后的对象
	 */
	public static String parseJWT(String token) {
		return JWT.require(Algorithm.HMAC256(password)).build().verify(token).getClaim("userId").asString();
	}
}

DecodedJWT jwt = JWT.decode(request.getHeader("token"));
System.out.println(jwt.getSubject()+"----------");

以上代码是JWT解析获取用户ID

编写JWT拦截器和JWT过滤器

package com.aqjyxt.Interceptor;

import java.util.HashMap;
import java.util.Map;

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

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

import com.aqjyxt.bean.JWTUtils;
import com.aqjyxt.bean.Returnben;
import com.auth0.jwt.exceptions.AlgorithmMismatchException;
import com.auth0.jwt.exceptions.SignatureVerificationException;
import com.auth0.jwt.exceptions.TokenExpiredException;
import com.auth0.jwt.interfaces.DecodedJWT;
import com.fasterxml.jackson.databind.ObjectMapper;

public class JWTInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
    	Returnben returnben = new Returnben();
 
        //获取请求头中的令牌
        String token = request.getHeader("token");
 
        try {
            //验证令牌
            DecodedJWT verify = JWTUtils.verify(token);
            return true;
        } catch (SignatureVerificationException e){
            e.printStackTrace();
            returnben.setMsg("无效签名");
			returnben.setSuccess("10001");
        } catch (TokenExpiredException e){
            e.printStackTrace();
            returnben.setMsg("token过期");
			returnben.setSuccess("10002");
        } catch (AlgorithmMismatchException e){
            e.printStackTrace();
            //token算法不一致
            returnben.setMsg("无效签名");
			returnben.setSuccess("10001");
        } catch (Exception e){
            e.printStackTrace();
            returnben.setMsg("token无效");
			returnben.setSuccess("10003");
        }
        //将map转为json
        String json = new ObjectMapper().writeValueAsString(returnben);
        response.setContentType("application/json;charset=UTF-8");
        response.getWriter().println(json);
        return false;
    }
}

package com.aqjyxt.Interceptor;

import java.util.ArrayList;
import java.util.List;

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 InterceptorConfig implements WebMvcConfigurer {
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
    	//下面list是放行swagger
        List l=new ArrayList();
    	l.add("/login");
    	l.add("/logout");
    	l.add("/css/**");
    	l.add("/js/**");
    	l.add("/index.html");
    	l.add("favicon.ico");
    	l.add("/doc.html");
    	l.add("/webjars/**");
    	l.add("/swagger-resources/**");
    	l.add("/v2/api-docs/**");

        registry.addInterceptor(new JWTInterceptor())
                //拦截 把需要拦截的请求配置
                .addPathPatterns("/systempc/*")
                //放行
                .excludePathPatterns("/user/login")
                .excludePathPatterns(l);
    }
}

 登录返回token

package com.aqjyxt.entity;

public class aqjyxt_user {

    private String id;

    private String user;

    private String password;

    private String username;

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id == null ? null : id.trim();
    }

    public String getUser() {
        return user;
    }

    public void setUser(String user) {
        this.user = user == null ? null : user.trim();
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password == null ? null : password.trim();
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username == null ? null : username.trim();
    }
}

@RequestMapping(value="/login",method = RequestMethod.POST)
	@ResponseBody
	@ApiOperation("登录接口")
	public Returnben login(HttpServletRequest request, HttpSession session,aqjyxt_user aqjyxt_user) {
		Returnben returnben = new Returnben();		
		String token = JWTUtils.getToken(aqjyxt_user);		
		returnben.setData(token);
		returnben.setMsg("成功");
		returnben.setSuccess("0");
		return returnben;

	}

从spring boot到spring cloud(七)整合JWT(Json Web Token)实现认证实例_第1张图片

从spring boot到spring cloud(七)整合JWT(Json Web Token)实现认证实例_第2张图片

你可能感兴趣的:(spring,java,spring,java,jwt)