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.拦截器

相关文章
|
3天前
|
缓存 安全 Java
Java服务器端技术:Servlet与JSP的集成与扩展
【6月更文挑战第23天】Java Web开发中,Servlet和JSP是构建动态Web应用的基础。Servlet处理逻辑,JSP专注展示。示例展示了Servlet如何通过`request.setAttribute`传递数据给JSP渲染。JSP自定义标签提升页面功能,如创建`WelcomeTag`显示欢迎消息。Servlet过滤器,如`CacheControlFilter`,用于预处理数据或调整响应头。这些集成和扩展技术增强了应用效率、安全性和可维护性,是Java服务器端开发的关键。
|
5天前
|
设计模式 SQL JavaScript
java面试宝典全套含答案
java面试宝典全套含答案
|
5天前
|
存储 Java
java面试题大全带答案_面试题库_java面试宝典2018
java面试题大全带答案_面试题库_java面试宝典2018
|
5天前
|
SQL 前端开发 Java
2019史上最全java面试题题库大全800题含答案(面试宝典)(4)
2019史上最全java面试题题库大全800题含答案(面试宝典)
|
5天前
|
SQL Java 数据库连接
2019史上最全java面试题题库大全800题含答案(面试宝典)(2)
2019史上最全java面试题题库大全800题含答案(面试宝典)
|
5天前
|
存储 设计模式 Java
java实习生面试题_java基础面试_java面试题2018及答案_java面试题库
java实习生面试题_java基础面试_java面试题2018及答案_java面试题库
|
5天前
|
SQL 算法 安全
java面试宝典_java基础面试_2018java面试题_2019java最新面试题
java面试宝典_java基础面试_2018java面试题_2019java最新面试题
|
5天前
|
算法 安全 网络协议
java高级面试题_java面试题大全带答案_线程面试题_java面试宝典2019
java高级面试题_java面试题大全带答案_线程面试题_java面试宝典2019
|
5天前
|
安全 算法 Java
java线程面试题_2019java面试题库
java线程面试题_2019java面试题库
|
5天前
|
前端开发 Dubbo Java
spring面试题_spring mvc面试题_springboot面试题库
spring面试题_spring mvc面试题_springboot面试题库