Java生成及校验token的实践

 更新时间:2024年04月14日 10:41:04   作者:夏诗曼CharmaineXia  
Token 的生成和校验机制为应用程序提供了一种安全的身份验证和授权方式,可以用于用户认证、API 访问控制等场景,本文主要介绍了Java生成及校验token的实践,具有一定的参考价值,感兴趣的可以了解一下

What is token?        

token是令牌的意思,作用就像“通关令牌”一样,持有token的请求会被“放行”,不持有token的请求可以被拦截(可以设置白名单使不被拦截,例如登陆请求)。

token是由服务端创建的一串字符串,登陆成功后发送给前端存储在浏览器或本地中,以后每次发送请求都携带上。

1. 使用拦截器在请求发出前在请求头中添加上 token。

2. 将 token 存储在浏览器的 cookies 中,符合一些条件每次请求都会自动带上 token。

Token安全问题

  • 在存储的时候把token进行对称加密存储,用时解开。 
  • 将请求URL、时间戳、token三者进行合并加盐签名,服务端校验有效性。 
  • 这两种办法的出发点都是:窃取你存储的数据较为容易,而反汇编你的程序hack你的加密解密和签名算法是比较难的。然而其实说难也不难,所以终究是防君子不防小人的做法。话说加密存储一个你要是被人扒开客户端看也不会被喷明文存储…… 
  • 方法1它拿到存储的密文解不开、方法2它不知道你的签名算法和盐,两者可以结合食用。 
  • 但是如果token被人拷走,他自然也能植入到自己的手机里面,那到时候他的手机也可以以你的身份来用着,这你就瞎了。 
  • 于是可以提供一个让用户可以主动expire一个过去的token类似的机制,在被盗的时候能远程止损。
  • 在网络层面上token明文传输的话会非常的危险,所以建议一定要使用HTTPS,并且把token放在post body里

Why do we use token?

在前后端分离的web项目中,HTTP是无状态协议,即使使用账号密码登陆,后端仍然无法分辨是谁发出的请求,要么后端不需要确认请求者的身份,要么每次请求都携带身份信息供后端确认。

显然第一种方法对软件的安全会造成极大的威胁,那么第二种方法就被改善成了token,token就是加密了的用户身份信息。

token组成(Composition of token)

以jwt(java web token)为例,下图介绍了详细介绍了token的组成。

校验token(Verify token)

这里只说最基础的校验。

token的加密一般是可逆的,后端接收到token中,还可以根据加密的算法再进行解密,以获取荷载中的用户信息,因此荷载中不能放置密码等信息。

第三部分由于加入了自己制定的秘钥(秘钥一般保存在后端代码中),解密成功后会与前两部分和保存的秘钥进行对比,对比成功了才算token验证通过。经过这样的双重保障,这三部分每一部分被篡改都会被发现。

校验流程:

实操:

生成token(Generate token)

以生成jwt为例子,代码如下:

        <!-- 引入jwt -->
        <dependency>
            <groupId>com.auth0</groupId>
            <artifactId>java-jwt</artifactId>
            <version>3.8.2</version>
        </dependency>

校验token(Verificationtoken) 

@Slf4j
public class JwtUtil {
    /**
     * 使用固定的解密秘钥
     */
    private static final String SECRET = TOKEN_SECRET;

    /**
     * @version: V1.0
     * @description: 生成token并验证token并解密token中的信息
     * @param:  userInfo 用户手机号和用户Id
     * @return: java.lang.String 返回token
     **/
    public static String getToken(UserInfoEntity userInfo) {
        try{
            //用秘钥生成签名
            Algorithm algorithm = Algorithm.HMAC256(SECRET);
            //默认头部+载荷(手机号/id)+签名=jwt
            String jwtToken= JWT.create()
                    .withClaim("userPhone", userInfo.getUserPhone())
                    .withClaim("userId", userInfo.getUserId())
                    .sign(algorithm);
            log.info("用户{}的token生成成功:{}",userInfo.getUserId(),jwtToken);
            return jwtToken;
        }catch (Exception e){
            log.error("用户{}的token生成异常:{}",userInfo.getUserId(),e);
            return null;
        }
    }

    /**
     * @version: V1.0
     * @description: 校验token是否正确
     * @param:  token
     * @param: userPhone
     * @return: UserInfoEntity token中的用户信息(姓名/id)
     **/
    public static UserInfoEntity verify(String token) {
        try {
            // 根据用户信息userInfo生成JWT效验器
            Algorithm algorithm = Algorithm.HMAC256(SECRET);
            JWTVerifier verifier = JWT.require(algorithm)
                    .build();
            // 效验TOKEN
            verifier.verify(token);
            log.info("token:{}校验成功成功",token);
            //返回token内容
            return getTokenInfo(token);
        } catch (Exception exception) {
            log.error("token校验异常:{}",exception);
            return null;
        }
    }

    /**
     * @version: V1.0
     * @Title: getUsername
     * @description: 从Token中解密获得Token中的用户信息
     * @param:  token
     * @return: UserInfoEntity token中的用户信息(姓名/id)
     **/
    private static UserInfoEntity getTokenInfo(String token) {
        try {
            DecodedJWT jwt = JWT.decode(token);
            UserInfoEntity userInfo=new UserInfoEntity();
            userInfo.setUserPhone(jwt.getClaim("userPhone").asString());
            userInfo.setUserId(jwt.getClaim("userId").asString());
            log.info("用户{}从token获取用户信息成功",userInfo.getUserId());
            return userInfo;
        } catch (JWTDecodeException e) {
            log.error("从token:{}获取用户信息异常:{}",token,e);
            return null;
        }
    }
}

总结:

在实际应用中,还应考虑安全性措施,如使用安全的随机数生成器生成密钥、定期更换密钥、使用 HTTPS 等。

Token 的生成和校验机制为应用程序提供了一种安全的身份验证和授权方式,可以用于用户认证、API 访问控制等场景。正确实现和使用 Token 机制可以提高应用程序的安全性和用户体验。

到此这篇关于Java生成及校验token的实践的文章就介绍到这了,更多相关Java生成及校验token内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:

相关文章

  • Java中关于线程安全的三种解决方式

    Java中关于线程安全的三种解决方式

    这篇文章主要介绍了Java中关于线程安全的三种解决方式,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-09-09
  • SpringBoot2零基础到精通之映射与常用注解请求处理

    SpringBoot2零基础到精通之映射与常用注解请求处理

    SpringBoot是一种整合Spring技术栈的方式(或者说是框架),同时也是简化Spring的一种快速开发的脚手架,本篇让我们一起学习映射、常用注解和方法参数的小技巧
    2022-03-03
  • SpringBoot批处理的实现示例

    SpringBoot批处理的实现示例

    SpringBatch是一个开源 的、全面的、轻量级的批处理框架,通过SpringBoot可以实现强大的批处理应用程序开发,本文主要介绍了SpringBoot批处理的实现示例,感兴趣的可以了解一下
    2022-03-03
  • Java实现商品的查找、添加、出库、入库操作完整案例

    Java实现商品的查找、添加、出库、入库操作完整案例

    这篇文章主要介绍了Java实现商品的查找、添加、出库、入库操作,结合完整实例形式分析了java基于面向对象的商品信息添加、删除、查找等相关操作技巧,需要的朋友可以参考下
    2019-11-11
  • Java LocalTime的常用时间操作总结

    Java LocalTime的常用时间操作总结

    日常开发中, 我们会经常遇到时间的运算, 操作, 格式化等, 这篇文章主要为大家详细介绍了LocalTime的常用时间操作,感兴趣的小伙伴可以了解一下
    2023-11-11
  • SpringBoot常见问题小结

    SpringBoot常见问题小结

    这篇文章主要介绍了SpringBoot常见问题小结,需要的朋友可以参考下
    2017-07-07
  • Java的带GUI界面猜数字游戏的实现示例

    Java的带GUI界面猜数字游戏的实现示例

    这篇文章主要介绍了Java的带GUI界面猜数字游戏的实现示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-12-12
  • IntelliJ IDEA 创建 Java 项目及创建 Java 文件并运行的详细步骤

    IntelliJ IDEA 创建 Java 项目及创建 Java 文件并运行的详细步骤

    这篇文章主要介绍了IntelliJ IDEA 创建 Java 项目及创建 Java 文件并运行的详细步骤,本文通过图文并茂的形式给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-11-11
  • 一篇文章带你了解JVM内存模型

    一篇文章带你了解JVM内存模型

    本文讲解了Java 内存模型来看看解决可见性、有序性问题的 Java 内存模型(JMM),今天通过本文给大家介绍Java 内存模型(JVM)的相关知识,感兴趣的朋友一起看看吧
    2021-09-09
  • Spring Boot 捕捉全局异常 统一返回值的问题

    Spring Boot 捕捉全局异常 统一返回值的问题

    这篇文章主要介绍了Spring Boot 捕捉全局异常 统一返回值,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-06-06

最新评论