springBoot集成token认证,最全Java面试知识点梳理

简介: springBoot集成token认证,最全Java面试知识点梳理

com.auth0

java-jwt

3.3.0

com.alibaba

fastjson

1.2.47

cn.hutool

hutool-all

5.4.4

注意:我们默认是已经配置好mybatis的web项目,还未配置myBatis?点击此处

2.自定义两个注解


用来跳过验证的PassToken

@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface PassToken {
boolean required() default true;
}

需要登录才能进行操作的注解UserLoginToken

@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface UserLoginToken {
boolean required() default true;
}

@Target:注解的作用目标

  • @Target(ElementType.TYPE)——接口、类、枚举、注解
  • @Target(ElementType.FIELD)——字段、枚举的常量
  • @Target(ElementType.METHOD)——方法
  • @Target(ElementType.PARAMETER)——方法参数
  • @Target(ElementType.CONSTRUCTOR) ——构造函数
  • @Target(ElementType.LOCAL_VARIABLE)——局部变量
  • @Target(ElementType.ANNOTATION_TYPE)——注解
  • @Target(ElementType.PACKAGE)——包

@Retention:注解的保留位置

  • RetentionPolicy.SOURCE:这种类型的Annotations只在源代码级别保留,编译时就会被忽略,在class字节码文件中不包含。
  • RetentionPolicy.CLASS:这种类型的Annotations编译时被保留,默认的保留策略,在class文件中存在,但JVM将会忽略,运行时无法获得。
  • RetentionPolicy.RUNTIME:这种类型的Annotations将被JVM保留,所以他们能在运行时被JVM或其他使用反射机制的代码所读取和使用。
  • @Document:说明该注解将被包含在javadoc中
  • @Inherited:说明子类可以继承父类中的该注解

3.简单自定义一个实体类User


public class User implements java.io.Serializable {
/** 版本号 */
private static final long serialVersionUID = 6111899065812654266L;
/** 主键自增Id */
private Integer userId;
/** 用户民 */
private String userName;
/** 用户密码 */
private String password;
/**
• 获取主键自增Id
• @return 主键自增Id
*/
public Integer getUserId() {
return this.userId;
}
/**
  • 设置主键自增Id

  • @param userId
主键自增Id
• 1
*/
public void setUserId(Integer userId) {
this.userId = userId;
}
/**
• 获取用户民
• @return 用户民
*/
public String getUserName() {
return this.userName;
}
/**
  • 设置用户民

  • @param userName
用户民
• 1
*/
public void setUserName(String userName) {
this.userName = userName;
}
/**
• 获取用户密码
• @return 用户密码
*/
public String getPassword() {
return this.password;
}
/**
  • 设置用户密码

  • @param password
用户密码
• 1
*/
public void setPassword(String password) {
this.password = password;
}
}

4.Mapper接口


public interface UserMapper {
public List getUserSelective(User user);
public User getUserByPrimary(Integer userId);
public User getUserByName(String userName);
}

5.service


UserService
public interface UserService {
/**
• 通过用户名获取唯一用户
• @param userName
• @return
*/
public User getUserByUserName(String userName);
/**
  • 根据条件获取用户
  • @param user
• @return
*/
public List getUserSelective(User user);
/**
• 通过主键获取用户
• @param userId
• @return
*/
public User getUserByUserId(Integer userId);
}

6.service的实现类


UserServiceImpl
@Service
public class UserServiceImpl implements UserService {
@Autowired
UserMapper userMapper;
@Override
public User getUserByUserName(String userName) {
User user=userMapper.getUserByName(userName);
return user;
}
@Override
public List getUserSelective(User user) {
return userMapper.getUserSelective(user);
}
@Override
public User getUserByUserId(Integer userId) {
return userMapper.getUserByPrimary(userId);
}
}

7.UserMapper.xml


u.user_id, u.user_name, u.password
SELECT
FROM user u WHERE 1 = 1
AND u.user_name LIKE CONCAT(‘%’, #{userName}, ‘%’)
AND u.password =#{password}
SELECT FROM User as u WHERE u.user_id =#{userId}
SELECT FROM User as u WHERE u.user_name =#{userName}
limit 1

8.token的生成方法


TokenUtils
package com.personal.indentity.utils;
import cn.hutool.core.date.DateUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.JWTDecodeException;
import com.auth0.jwt.interfaces.Claim;
import com.auth0.jwt.interfaces.DecodedJWT;
import javax.servlet.http.HttpServletRequest;
import java.util.Arrays;
import java.util.Date;
import java.util.Map;
public class TokenUtils {
/**
• 签名秘钥
*/
private static final String SECRET = “zx12345678”;
/**
• 签发人
*/
private static final String issuer=“zhiyi”;
/**
• token过期时间,单位:min
*/
private static final Integer expireTime=2;
/**
• 从header中取token
• @return
*/
public static String getToken(){
HttpServletRequest request =WebUtils.getRequest();
String re=request.getHeader(“token”);
return re;
}
/**
• 创建token
• @param json 需要放入token的参数,多个参数可以封装成json或者map
• @return token
*/
public static String createToken(JSONObject json) {
try {
// 加密方式
Algorithm algorithm = Algorithm.HMAC256(SECRET);
return JWT.create()
.withSubject(json.toString())
.withIssuer(issuer)
// 设置过期时间为60分钟后
.withExpiresAt(DateUtil.offsetMinute(new Date(), expireTime))
.withClaim(“customString”, “zhiyi”)
.withArrayClaim(“customArray”, new Integer[]{1, 2, 3})
.sign(algorithm);
} catch (Exception exception) {
//Invalid Signing configuration / Couldn’t convert Claims.
System.out.println(exception.getMessage());
return null;
}
}
/**
• 校验token合法性
• @param token to verify.
*/
public static boolean verifyToken(String token) {
try {
Algorithm algorithm = Algorithm.HMAC256(SECRET);
JWTVerifier verifier = JWT.require(algorithm)
// 验证签发人是否相同
.withIssuer(issuer)
.build();
/*
• 校验:
• 格式校验:header.payload.signature
• 加密方式校验 Header中的alg
• 签名信息校验,防篡改
• 载体Payload 中公有声明字段校验
*/
verifier.verify(token);
return true;
} catch (Exception exception) {
//Invalid signature/claims
exception.printStackTrace();
return false;
}
}
/**
• 解析token
• @param token to decode.
*/
public static void decodeToken(String token) {
try {
DecodedJWT jwt = JWT.decode(token);
Map claims = jwt.getClaims();
Claim customStringClaim = claims.get(“customString”);
Claim customArrayClaim = claims.get(“customArray”);
String issuer = jwt.getIssuer();
String subject = jwt.getSubject();
System.out.println(customStringClaim.asString());
System.out.println(Arrays.toString(customArrayClaim.asArray(Integer.class)));
System.out.println(issuer);
System.out.println(JSONUtil.parseObj(subject).get(“userId”));
} catch (JWTDecodeException exception) {
//Invalid token
exception.printStackTrace();
}
}
public static String getUserIdByToken(String token){
DecodedJWT jwt = JWT.decode(token);
Map claims = jwt.getClaims();
String subject = jwt.getSubject();
String re=JSONUtil.parseObj(subject).get(“userId”).toString();
return re;
}
public static void main(String[] args) {
JSONObject subjectJson = new JSONObject();
subjectJson.put(“userId”, 1);
subjectJson.put(“name”, “ylc”);
String token = createToken(subjectJson);
System.out.println(“token:” + token);
System.out.println(“==============================================”);
//
// System.out.println(“1 min exp,now verify result:” + verifyToke(token));
// System.out.println(“==============================================”);
//
// System.out.println(“decode info:”);
// decodeToken(token);
// System.out.println(“================================================”);
// System.out.println(“1 min later,verify result:”+verifyToke(“eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJ7XCJ1c2VySWRcIjoxLFwibmFtZVwiOlwieWxjXCJ9IiwiaXNzIjoiemhpeWkiLCJleHAiOjE2MDIzMzI2OTMsImN1c3RvbUFycmF5IjpbMSwyLDNdLCJjdXN0b21TdHJpbmciOiJ6aGl5aSJ9.v6AQ2mba8gGsHFpJ52EY4fwoN03gEDsCUUSafpPscyQ”));
// System.out.println(“================================================”);
System.out.println(“userId:”+getUserIdByToken(“eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJ7XCJ1c2VySWRcIjoxLFwibmFtZVwiOlwieWxjXCJ9IiwiaXNzIjoiemhpeWkiLCJleHAiOjE2MDIzMzM1MjEsImN1c3RvbUFycmF5IjpbMSwyLDNdLCJjdXN0b21TdHJpbmciOiJ6aGl5aSJ9.BKU-X6Bre9kCbsCtQgwDO6UE7znqbM84xy8dH6R7AiY”));
}
}
WebUtils
package com.dubbo.consumer.indentity.util;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
public class WebUtils {
/**
• 获取request
• @return
*/
public static HttpServletRequest getRequest() {
ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder
.getRequestAttributes();
return requestAttributes == null ? null : requestAttributes.getRequest();
}
/**
• 获取session
• @return
*/
public static HttpSession getSession() {
HttpSession session = getRequest().getSession();
return session;
}
}

Algorithm.HMAC256():使用HS256生成token,密钥则是用户的密码,唯一密钥的话可以保存在服务端。

withAudience()存入需要保存在token的信息,这里我把用户ID存入token中

9.拦截器

相关文章
|
8天前
|
存储 算法 Java
大厂面试高频:什么是自旋锁?Java 实现自旋锁的原理?
本文详解自旋锁的概念、优缺点、使用场景及Java实现。关注【mikechen的互联网架构】,10年+BAT架构经验倾囊相授。
大厂面试高频:什么是自旋锁?Java 实现自旋锁的原理?
|
9天前
|
存储 缓存 Java
大厂面试必看!Java基本数据类型和包装类的那些坑
本文介绍了Java中的基本数据类型和包装类,包括整数类型、浮点数类型、字符类型和布尔类型。详细讲解了每种类型的特性和应用场景,并探讨了包装类的引入原因、装箱与拆箱机制以及缓存机制。最后总结了面试中常见的相关考点,帮助读者更好地理解和应对面试中的问题。
33 4
|
1月前
|
JavaScript 前端开发 Java
解决跨域问题大集合:vue-cli项目 和 java/springboot(6种方式) 两端解决(完美解决)
这篇文章详细介绍了如何在前端Vue项目和后端Spring Boot项目中通过多种方式解决跨域问题。
334 1
解决跨域问题大集合:vue-cli项目 和 java/springboot(6种方式) 两端解决(完美解决)
|
15天前
|
监控 前端开发 Java
Java SpringBoot –性能分析与调优
Java SpringBoot –性能分析与调优
|
18天前
|
JavaScript Java 项目管理
Java毕设学习 基于SpringBoot + Vue 的医院管理系统 持续给大家寻找Java毕设学习项目(附源码)
基于SpringBoot + Vue的医院管理系统,涵盖医院、患者、挂号、药物、检查、病床、排班管理和数据分析等功能。开发工具为IDEA和HBuilder X,环境需配置jdk8、Node.js14、MySQL8。文末提供源码下载链接。
|
23天前
|
JSON Java Maven
实现Java Spring Boot FCM推送教程
本指南介绍了如何在Spring Boot项目中集成Firebase云消息服务(FCM),包括创建项目、添加依赖、配置服务账户密钥、编写推送服务类以及发送消息等步骤,帮助开发者快速实现推送通知功能。
61 2
|
28天前
|
人工智能 JavaScript 网络安全
ToB项目身份认证AD集成(三完):利用ldap.js实现与windows AD对接实现用户搜索、认证、密码修改等功能 - 以及针对中文转义问题的补丁方法
本文详细介绍了如何使用 `ldapjs` 库在 Node.js 中实现与 Windows AD 的交互,包括用户搜索、身份验证、密码修改和重置等功能。通过创建 `LdapService` 类,提供了与 AD 服务器通信的完整解决方案,同时解决了中文字段在 LDAP 操作中被转义的问题。
|
30天前
|
架构师 Java 开发者
得物面试:Springboot自动装配机制是什么?如何控制一个bean 是否加载,使用什么注解?
在40岁老架构师尼恩的读者交流群中,近期多位读者成功获得了知名互联网企业的面试机会,如得物、阿里、滴滴等。然而,面对“Spring Boot自动装配机制”等核心面试题,部分读者因准备不足而未能顺利通过。为此,尼恩团队将系统化梳理和总结这一主题,帮助大家全面提升技术水平,让面试官“爱到不能自已”。
得物面试:Springboot自动装配机制是什么?如何控制一个bean 是否加载,使用什么注解?
|
1月前
|
算法 Java 数据中心
探讨面试常见问题雪花算法、时钟回拨问题,java中优雅的实现方式
【10月更文挑战第2天】在大数据量系统中,分布式ID生成是一个关键问题。为了保证在分布式环境下生成的ID唯一、有序且高效,业界提出了多种解决方案,其中雪花算法(Snowflake Algorithm)是一种广泛应用的分布式ID生成算法。本文将详细介绍雪花算法的原理、实现及其处理时钟回拨问题的方法,并提供Java代码示例。
67 2
|
21天前
|
缓存 Java 程序员
Java|SpringBoot 项目开发时,让 FreeMarker 文件编辑后自动更新
在开发过程中,FreeMarker 文件编辑后,每次都需要重启应用才能看到效果,效率非常低下。通过一些配置后,可以让它们免重启自动更新。
23 0