SpringBoot整合token实现登录认证的示例代码

 更新时间:2022年07月07日 11:00:38   作者:小浪饿了吗***  
本文主要介绍了SpringBoot整合token实现登录认证的示例代码,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

1.pom.xml

<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
		</dependency>
		
		<dependency>
		      <groupId>com.auth0</groupId>
		      <artifactId>java-jwt</artifactId>
		      <version>3.4.0</version>
		</dependency>
		
		 <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>
        
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>1.3.2</version>
        </dependency>
        
		 <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.47</version>
        </dependency>

		<dependency>
			<groupId>io.springfox</groupId>
			<artifactId>springfox-swagger2</artifactId>
			<version>2.8.0</version>
		</dependency>
		<dependency>
			<groupId>io.springfox</groupId>
			<artifactId>springfox-swagger-ui</artifactId>
			<version>2.8.0</version>
		</dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.0</version>
        </dependency>

    </dependencies>

2.实体类

@Data
public class User {
	private String id;
    private String username;
    private String password;
}

3.Mapper接口

/**
 * @author qiaoyn
 * @date 2019/06/14
 */
@Mapper
public interface UserMapper {
	
    User findByUsername(String username);
    
    User findUserById(String id);
}

4.service层

@Service
public class UserService {
    @Autowired
    private UserMapper userMapper;
    public User findByUsername(User user){
        return userMapper.findByUsername(user.getUsername());
    }
    public User findUserById(String userId) {
        return userMapper.findUserById(userId);
    }
}
/***
 * token 下发
* @Title: TokenService.java 
* @author qiaoyn
* @date 2019/06/14
* @version V1.0
 */
@Service
public class TokenService {

	public String getToken(User user) {
		Date start = new Date();
		long currentTime = System.currentTimeMillis() + 60* 60 * 1000;//一小时有效时间
		Date end = new Date(currentTime);
		String token = "";
		
		token = JWT.create().withAudience(user.getId()).withIssuedAt(start).withExpiresAt(end)
				.sign(Algorithm.HMAC256(user.getPassword()));
		return token;
	}
}

5.Api层

@RestController
public class UserApi {
	@Autowired
	UserService userService;
	@Autowired
	TokenService tokenService;

	// 登录
	@ApiOperation(value = "登陆", notes = "登陆")
	@RequestMapping(value = "/login" ,method = RequestMethod.GET)
	public Object login(User user, HttpServletResponse response) {
		JSONObject jsonObject = new JSONObject();
		User userForBase = new User();
		userForBase.setId(userService.findByUsername(user).getId());
		userForBase.setUsername(userService.findByUsername(user).getUsername());
		userForBase.setPassword(userService.findByUsername(user).getPassword());
		if (!userForBase.getPassword().equals(user.getPassword())) {
			jsonObject.put("message", "登录失败,密码错误");
			return jsonObject;
		} else {
			String token = tokenService.getToken(userForBase);
			jsonObject.put("token", token);

			Cookie cookie = new Cookie("token", token);
			cookie.setPath("/");
			response.addCookie(cookie);

			return jsonObject;

		}
	}
	/***
	 * 这个请求需要验证token才能访问
	 * 
	 * @author: qiaoyn
	 * @date 2019/06/14
	 * @return String 返回类型
	 */
	@UserLoginToken
	@ApiOperation(value = "获取信息", notes = "获取信息")
	@RequestMapping(value = "/getMessage" ,method = RequestMethod.GET)
	public String getMessage() {

		// 取出token中带的用户id 进行操作
		System.out.println(TokenUtil.getTokenUserId());

		return "您已通过验证";
	}
}

6.util

/* 
* @author qiaoyn
* @date 2019/06/14
* @version 1.0 
*/
public class TokenUtil {

	public static String getTokenUserId() {
		String token = getRequest().getHeader("token");// 从 http 请求头中取出 token
		String userId = JWT.decode(token).getAudience().get(0);
		return userId;
	}

	/**
	 * 获取request
	 * 
	 * @return
	 */
	public static HttpServletRequest getRequest() {
		ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder
				.getRequestAttributes();
		return requestAttributes == null ? null : requestAttributes.getRequest();
	}
}

7.Interceptor

/**
 * 拦截器
 * @author qiaoyn
 * @date 2019/06/14
 */
public class AuthenticationInterceptor implements HandlerInterceptor {
    @Autowired
    UserService userService;
    @Override
    public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object object) throws Exception {
        String token = httpServletRequest.getHeader("token");// 从 http 请求头中取出 token
        // 如果不是映射到方法直接通过
        if(!(object instanceof HandlerMethod)){
            return true;
        }
        HandlerMethod handlerMethod=(HandlerMethod)object;
        Method method=handlerMethod.getMethod();
        //检查是否有passtoken注释,有则跳过认证
        if (method.isAnnotationPresent(PassToken.class)) {
            PassToken passToken = method.getAnnotation(PassToken.class);
            if (passToken.required()) {
                return true;
            }
        }
        //检查有没有需要用户权限的注解
        if (method.isAnnotationPresent(UserLoginToken.class)) {
            UserLoginToken userLoginToken = method.getAnnotation(UserLoginToken.class);
            if (userLoginToken.required()) {
                // 执行认证
                if (token == null) {
                    throw new RuntimeException("无token,请重新登录");
                }
                // 获取 token 中的 user id
                String userId;
                try {
                    userId = JWT.decode(token).getAudience().get(0);
                } catch (JWTDecodeException j) {
                    throw new RuntimeException("401");
                }
                User user = userService.findUserById(userId);
                if (user == null) {
                    throw new RuntimeException("用户不存在,请重新登录");
                }
                // 验证 token
                JWTVerifier jwtVerifier = JWT.require(Algorithm.HMAC256(user.getPassword())).build();
                try {
                    jwtVerifier.verify(token);
                } catch (JWTVerificationException e) {
                    throw new RuntimeException("401");
                }
                return true;
            }
        }
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {

    }
    @Override
    public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {

    }
}

8.cofig

/***
 * 新建Token拦截器
* @Title: InterceptorConfig.java 
* @author qiaoyn
* @date 2019/06/14
* @version V1.0
 */
@Configuration
public class InterceptorConfig implements WebMvcConfigurer {
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(authenticationInterceptor())
                .addPathPatterns("/**");    // 拦截所有请求,通过判断是否有 @LoginRequired 注解 决定是否需要登录
    }
    @Bean
    public AuthenticationInterceptor authenticationInterceptor() {
        return new AuthenticationInterceptor();
    }
	@Override
	public void addArgumentResolvers(List<HandlerMethodArgumentResolver> arg0) {
		// TODO Auto-generated method stub
		
	}
	@Override
	public void addCorsMappings(CorsRegistry arg0) {
		// TODO Auto-generated method stub
		
	}
	@Override
	public void addFormatters(FormatterRegistry arg0) {
		// TODO Auto-generated method stub
		
	}
	@Override
	public void addResourceHandlers(ResourceHandlerRegistry arg0) {
		// TODO Auto-generated method stub
		
	}
	@Override
	public void addReturnValueHandlers(List<HandlerMethodReturnValueHandler> arg0) {
		// TODO Auto-generated method stub
		
	}
	@Override
	public void addViewControllers(ViewControllerRegistry arg0) {
		// TODO Auto-generated method stub
		
	}
	@Override
	public void configureAsyncSupport(AsyncSupportConfigurer arg0) {
		// TODO Auto-generated method stub
		
	}
	@Override
	public void configureContentNegotiation(ContentNegotiationConfigurer arg0) {
		// TODO Auto-generated method stub
		
	}
	@Override
	public void configureDefaultServletHandling(DefaultServletHandlerConfigurer arg0) {
		// TODO Auto-generated method stub
		
	}
	@Override
	public void configureHandlerExceptionResolvers(List<HandlerExceptionResolver> arg0) {
		// TODO Auto-generated method stub
		
	}
	@Override
	public void configureMessageConverters(List<HttpMessageConverter<?>> arg0) {
		// TODO Auto-generated method stub
		
	}
	@Override
	public void configurePathMatch(PathMatchConfigurer arg0) {
		// TODO Auto-generated method stub
		
	}
	@Override
	public void configureViewResolvers(ViewResolverRegistry arg0) {
		// TODO Auto-generated method stub
		
	}
	@Override
	public void extendHandlerExceptionResolvers(List<HandlerExceptionResolver> arg0) {
		// TODO Auto-generated method stub
		
	}
	@Override
	public void extendMessageConverters(List<HttpMessageConverter<?>> arg0) {
		// TODO Auto-generated method stub
		
	}
	@Override
	public MessageCodesResolver getMessageCodesResolver() {
		// TODO Auto-generated method stub
		return null;
	}
	@Override
	public Validator getValidator() {
		// TODO Auto-generated method stub
		return null;
	}
	
}

9.annotation

/***
 * 用来跳过验证的 PassToken
 * @author qiaoyn
 * @date 2019/06/14
 */
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface PassToken {
    boolean required() default true;
}
/**
 * 用于登录后才能操作的token
 * @author qiaoyn
 * @date 2019/06/14
 */
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface UserLoginToken {
    boolean required() default true;
}

/*RetentionPolicy.RUNTIME:这种类型的Annotations将被JVM保留,
所以他们能在运行时被JVM或其他使用反射机制的代码所读取和使用。*/

10.mapper.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.example.demo.mapper.UserMapper">
    <select id="findByUsername" resultType="com.example.demo.entity.User">
      SELECT id,password
      FROM user
      WHERE
      username=#{username}
    </select>
    <select id="findUserById" resultType="com.example.demo.entity.User">
        SELECT username,password
        FROM user
        WHERE
        id=#{id}
    </select>

</mapper>

11.测试

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

数据库文件如下所示

在这里插入图片描述

到此这篇关于SpringBoot整合token实现登录认证的示例代码的文章就介绍到这了,更多相关SpringBoot token登录认证内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • java中JSONObject转换为HashMap(方法+main方法调用实例)

    java中JSONObject转换为HashMap(方法+main方法调用实例)

    这篇文章主要介绍了java中JSONObject转换为HashMap(方法+main方法调用实例),文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-11-11
  • 一文带你搞懂Spring响应式编程

    一文带你搞懂Spring响应式编程

    相信响应式编程经常会在各种地方被提到。本篇就为大家从函数式编程一直到Spring WeFlux做一次简单的讲解,并给出一些示例,希望大家可以更好的理解响应式编程
    2022-07-07
  • Spring 循环依赖之AOP实现详情

    Spring 循环依赖之AOP实现详情

    这篇文章主要介绍了Spring 循环依赖之AOP实现详情,文章围绕主题展开详细的内容介绍,具有一定的参考价值,需要的盆友可以参考一下
    2022-07-07
  • Java基础教程之List集合的常用方法

    Java基础教程之List集合的常用方法

    这篇文章主要给大家介绍了关于Java基础教程之List集合的常用方法,在Java编程中List集合是一种常用的数据结构,用于存储一组元素,有时候我们需要对List集合中的元素进行分组操作,即将相同属性或特征的元素归类到一组,需要的朋友可以参考下
    2023-10-10
  • 利用Spring AOP记录方法的执行时间

    利用Spring AOP记录方法的执行时间

    这篇文章给大家介绍的是spring的aop来实现方法级的执行时间的记录监控,以此来评估方法的性能以及针对性的对已存在的方法进行优化。对于监控,我们比较关注监控的可靠性和性能,准确,高效,这才能在不影响整体性能的情况下对我们的系统性能有个较准确的认识。
    2016-09-09
  • java乐观锁原理与实现案例分析

    java乐观锁原理与实现案例分析

    这篇文章主要介绍了java乐观锁原理与实现,结合具体案例形式分析了乐观锁的原理及java使用乐观锁实现自动派单功能的相关操作技巧,需要的朋友可以参考下
    2019-10-10
  • Java进阶教程之异常处理

    Java进阶教程之异常处理

    这篇文章主要介绍了Java进阶教程之异常处理,本文讲解了JAVA的异常处理机制、异常的类型、抛出异常、自定义异常等内容,需要的朋友可以参考下
    2014-09-09
  • Java使用apache poi操作excel的方式

    Java使用apache poi操作excel的方式

    这篇文章主要介绍了Java使用apache poi进行excel相关操作,本文主要针对Apache POI对excel的操作进行介绍,主要包括如何创建一个excel、录入数据、读取excel数据的方式,需要的朋友可以参考下
    2022-05-05
  • Android中几种图片特效的处理的实现方法

    Android中几种图片特效的处理的实现方法

    这篇文章主要介绍了 Android中几种图片特效的处理的实现方法的相关资料,这里有放大缩小图片,获得圆角图片,获得带倒影图片的几种方法,需要的朋友可以参考下
    2017-08-08
  • Spring Data中domain模块的使用

    Spring Data中domain模块的使用

    Spring Data是一个流行的数据访问框架,本文主要介绍了Spring Data中domain模块的使用,并展示如何使用它来优化我们的数据访问层,具有一定的参考价值,感兴趣的可以了解一下
    2024-03-03

最新评论