补充知识点五:基于Token的WEB后台认证机制

理论基础参见:
基于Token的WEB后台认证机制
简单样例参见:
【JWT】JWT+HA256加密 Token验证
JSON Web Token - 在Web应用间安全地传递信息

应用实例:
JWT——Token认证的两种实现和安全详解

自己写的实例:
1.引入JAR包

<dependency>
            <groupId>io.jsonwebtoken</groupId>
            <artifactId>jjwt</artifactId>
            <version>0.9.0</version>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.28</version>
        </dependency>

2.生成token,校验token

package org.pc;


import com.alibaba.fastjson.JSONObject;
import io.jsonwebtoken.*;
import io.jsonwebtoken.impl.Base64Codec;

import javax.crypto.spec.SecretKeySpec;
import javax.xml.bind.DatatypeConverter;
import java.security.Key;

/**
 * @author **
 * @date 2018/6/8 8:47
 * Token认证:
 *     JWT 标准的 Token 有三个部分:
 *     1.header(头部),头部信息主要包括(参数的类型--JWT,签名的算法--HS256)
 *     2.payload(负荷),负荷基本就是自己想要存放的信息(因为信息会暴露,不应该在载荷里面加入任何敏感的数据),有两个形式,下边会讲到
 *     3.sign(签名),签名的作用就是为了防止恶意篡改数据
 *     中间用点("\\.")分隔开,并且都会使用 Base64 编码
 */
public final class JwtTokenUtil {
    /**
     * 创建token
     * @param payload 负荷
     * @return 签名
     * 备注:我们这里是借助第三方框架:jjwt实现创建token,它实际的流程是:
     * 第一步:对header(头部)进行 Base64 编码 --------> #######
     * 第二步:对payload(负荷)进行 Base64 编码 --------> *******
     * 第三步:JWT 的最后一部分是 Signature ,这部分内容有三个部分,先是用 Base64 编码的 header.payload ,
     *         再用加密算法加密一下,加密的时候要放进去一个 Secret ,这个相当于是一个密码,这个密码秘密地
     *         存储在服务端。
     * var encodedString = base64UrlEncode(header) + "." + base64UrlEncode(payload);
     * HMACSHA256(encodedString, 'secret');
     */
    public static String createToken(String payload){
        System.out.println("负荷的值:" + payload);
        SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;
        //这个在实际项目中,秘钥要配置在配置文件中
        String secretKey = "king";
        byte[] secretKeyBytes = DatatypeConverter.parseBase64Binary(secretKey);
        Key signKey = new SecretKeySpec(secretKeyBytes, signatureAlgorithm.getJcaName());
        JwtBuilder builder = Jwts.builder()
                //设置header
                .setHeaderParam("typ", "JWT")
                .setHeaderParam("alg", "HS256")
                //设置payload
                .setPayload(payload)
                //签名
                .signWith(signatureAlgorithm, signKey);
        return builder.compact();
    }

    /**
     * 验证前端传送过来的token
     * 备注:若过期,会抛出异常
     */
    public static Claims parseToken(String token){
        //秘钥
        String secretKey = "king";
        String[] tokens = token.split("\\.");
        if (tokens.length == 3){
            //header(头部)
            String header = tokens[0];
            //payload(负荷)
            String payload = tokens[1];
            //利用Base64解码(为什么用Base64解码,参见创建token)
            System.out.println("负荷:" + Base64Codec.BASE64URL.decodeToString(payload));
            //签名
            String sign = tokens[2];
            System.out.println("签名:" + sign);
            //头部
            JwsHeader claimsHeader = Jwts.parser().setSigningKey(DatatypeConverter.parseBase64Binary(secretKey))
                    .parseClaimsJws(token).getHeader();
            //负荷
            Claims claimsPayload = Jwts.parser().setSigningKey(DatatypeConverter.parseBase64Binary(secretKey))
                    .parseClaimsJws(token).getBody();
            String signNew = createToken(JSONObject.toJSONString(claimsPayload));
            if (signNew != null && signNew.equals(token)){
                System.out.println("匹配");
            }
            return claimsPayload;
        } else {
            return null;
        }
    }

    public static void main(String[] args){
        JSONObject jsonPayload = new JSONObject();
        jsonPayload.put("iss", "ninghao.net");
        //若过期,会抛出异常
        jsonPayload.put("exp", System.currentTimeMillis()+1000);
        jsonPayload.put("name", "wanghao");
        jsonPayload.put("admin", true);
        String token = JwtTokenUtil.createToken(jsonPayload.toJSONString());
        JwtTokenUtil.parseToken(token);
    }
}

猜你喜欢

转载自blog.csdn.net/panchang199266/article/details/80617573