token的组成和使用

本文你能学到什么?

token的组成 
token串的生成流程。 
token在客户端与服务器端的交互流程 
Token的优点和思考 
参考代码:核心代码使用参考,不是全部代码

JWT token的组成

头部(Header),格式如下: 
{ 
“typ”: “JWT”, 
“alg”: “HS256” 
} 
由上可知,该token使用HS256加密算法,将头部使用Base64编码可得到如下个格式的字符串:

eyJhbGciOiJIUzI1NiJ91

有效载荷(Playload): 
{  
  “iss”: “Online JWT Builder”,  
  “iat”: 1416797419,  
  “exp”: 1448333419,  
      ……. 
  “userid”:10001 
} 
有效载荷中存放了token的签发者(iss)、签发时间(iat)、过期时间(exp)等以及一些我们需要写进token中的信息。有效载荷也使用Base64编码得到如下格式的字符串:

eyJ1c2VyaWQiOjB91

签名(Signature): 
将Header和Playload拼接生成一个字符串str=“eyJhbGciOiJIUzI1NiJ9.eyJ1c2VyaWQiOjB9”,使用HS256算法和我们提供的密钥(secret,服务器自己提供的一个字符串)对str进行加密生成最终的JWT,即我们需要的令牌(token),形如:str.”签名字符串”。

token在服务与客户端的交互流程

1:客户端通过用户名和密码登录 
2:服务器验证用户名和密码,若通过,生成token返回给客户端。 
3:客户端收到token后以后每次请求的时候都带上这个token,相当于一个令牌,表示我有权限访问了 
4:服务器接收(通常在拦截器中实现)到该token,然后验证该token的合法性(为什么能验证下面说)。若该token合法,则通过请求,若token不合法或者过期,返回请求失败。



关于Token的思考

服务如何判断这个token是否合法? 
由上面token的生成可知,token中的签名是由Header和有效载荷通过Base64编码生成再通过加密算法HS256和密钥最终生成签名,这个签名位于JWT的尾部,在服务器端同样对返回过来的JWT的前部分再进行一次签名生成,然后比较这次生成的签名与请求的JWT中的签名是否一致,若一致说明token合法。由于生成签名的密钥是服务器才知道的,所以别人难以伪造。

token中能放敏感信息吗? 
不能,因为有效载荷是经过Base64编码生成的,并不是加密。所以不能存放敏感信息。



Token的优点

(1)相比于session,它无需保存在服务器,不占用服务器内存开销。 
(2)无状态、可拓展性强:比如有3台机器(A、B、C)组成服务器集群,若session存在机器A上,session只能保存在其中一台服务器,此时你便不能访问机器B、C,因为B、C上没有存放该Session,而使用token就能够验证用户请求合法性,并且我再加几台机器也没事,所以可拓展性好就是这个意思。 
(3)由(2)知,这样做可就支持了跨域访问。



Java实例:JWT token使用

部分代码来自互联网,找不到原作者了。。 
编写JWT(Java Web Token)操作类:JavaWebToken



public class JavaWebToken {

    private static Logger log = LoggerFactory.getLogger(JavaWebToken.class);

    //该方法使用HS256算法和Secret:bankgl生成signKey
    private static Key getKeyInstance() {
        //We will sign our JavaWebToken with our ApiKey secret
        SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;
        byte[] apiKeySecretBytes = DatatypeConverter.parseBase64Binary("bankgl");
        Key signingKey = new SecretKeySpec(apiKeySecretBytes, signatureAlgorithm.getJcaName());
        return signingKey;
    }

    //使用HS256签名算法和生成的signingKey最终的Token,claims中是有效载荷
    public static String createJavaWebToken(Map<String, Object> claims) {
        return Jwts.builder().setClaims(claims).signWith(SignatureAlgorithm.HS256, getKeyInstance()).compact();
    }

    //解析Token,同时也能验证Token,当验证失败返回null
    public static Map<String, Object> parserJavaWebToken(String jwt) {
        try {
            Map<String, Object> jwtClaims =
                    Jwts.parser().setSigningKey(getKeyInstance()).parseClaimsJws(jwt).getBody();
            return jwtClaims;
        } catch (Exception e) {
            log.error("json web token verify failed");
            return null;
        }
    }
}123456789101112131415161718192021222324252627282930

编写登录Conreoller,在服务器端给客户返回token.



public LoginStatusMessage checkUserAndPassword(
    @RequestParam(value="username",required=true) String username,
    @RequestParam(value="password",required=true) String password,User user,HttpServletRequest request) throws Exception{
        User u = new User();
        //登录成功
        if((u = userService.checkUsernameAndPassword(user)) != null){
            Map<String,Object> m = new HashMap<String,Object>();
            m.put("userid", user.getUserid());
            String token = JavaWebToken.createJavaWebToken(m);
            System.out.println(token);
            LoginStatusMessage lsm = new LoginStatusMessage();
            lsm.setUser(u);
            lsm.setToken(token);
            return lsm;
        };
        //登录失败,返回Null
        return null;
    }123456789101112131415161718

在拦截器中对请求中的Token验证(部分代码,表示下意思):



String token = request.getParameter("token");
            if(JavaWebToken.parserJavaWebToken(token) != null){
                //表示token合法
                return true;
            }else{
                //token不合法或者过期
                return false;
            }

---------------------

本文来自 bug_lover_liao 的优快云 博客 ,全文地址请点击:https://blog.youkuaiyun.com/csdn_blog_lcl/article/details/73485463?utm_source=copy 

 

<think>我们正在讨论token组成部分。根据引用[1]引用[2],token通常由三部分组成:头部(Header)、载荷(Payload)签名(Signature)。下面我将详细解释每个部分。</think>### Token组成部分详解 Token 通常由三部分组成,采用标准化的结构设计以确保安全性可验证性: #### 1. **头部 (Header)** - **作用**:声明 Token 的类型签名算法 - **内容**: - `typ`:Token 类型(如 `JWT`) - `alg`:签名算法(如 `HS256`、`RS256`) - **示例**: ```json { "alg": "HS256", "typ": "JWT" } ``` - **存储形式**:Base64Url 编码[^1] #### 2. **载荷 (Payload)** - **作用**:携带实际业务数据声明 - **内容分类**: - **标准声明**(预定义字段): - `iss`:签发者 - `exp`:过期时间 - `sub`:主题 - `aud`:接收方 - **公共声明**:自定义业务数据(如用户ID、角色权限) - **私有声明**:双方约定的自定义字段 - **示例**: ```json { "sub": "user123", "name": "张三", "role": "admin", "exp": 1735689600 } ``` - **存储形式**:Base64Url 编码[^1][^2] #### 3. **签名 (Signature)** - **作用**:验证 Token 完整性防篡改 - **生成方式**: ```js HMACSHA256( base64UrlEncode(header) + "." + base64UrlEncode(payload), secretKey ) ``` - **验证原理**: - 服务器用相同算法密钥重新计算签名 - 对比计算结果与 Token 中的签名是否一致 - **安全意义**: - 确保头部载荷未被篡改 - 验证 Token 来源真实性[^2] ### Token 完整结构示例 ``` eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9. // 头部(Base64编码) eyJzdWIiOiJ1c2VyMTIzIiwibmFtZSI6IuW8oOWbviIsInJvbGUiOiJhZG1pbiJ9. // 载荷(Base64编码) SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c // 签名 ``` ### 各部分的安全意义 1. **头部**:指定算法防止攻击者篡改签名方式[^1] 2. **载荷**:Base64编码可读但不加密,敏感数据需额外加密 3. **签名**: - 对称算法(如 `HS256`):需共享密钥 - 非对称算法(如 `RS256`):私钥签名,公钥验证 - 防止中间人篡改关键字段(如用户权限 `role`)[^2] --- ### 相关问题 1. **JWT 与 OAuth Token 在结构上有何区别?** 2. **如何安全地在 Token 载荷中存储敏感信息?** 3. **签名算法 HS256 RS256 在安全性上有何差异?** 4. **Token 过期机制(exp 字段)如何实现?有哪些最佳实践?** [^1]: Token 一般由三部分组成:头部、载荷部分签名部分。头部包含了 Token 的类型加密算法。 [^2]: 签名是 token 的第三部分,确保 token 在传输过程中没有被篡改。
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值