使用Token进行身份验证

一、作为计算机术语时,是“令牌”的意思

token是计算机术语:令牌,令牌是一种能够控制站点占有媒体的特殊帧,以区别数据帧及其他控制帧。token其实说的更通俗点可以叫暗号,在一些数据传输之前,要先进行暗号的核对,不同的暗号被授权不同的数据操作。基于 Token 的身份验证方法

使用基于 Token 的身份验证方法,在服务端不需要存储用户的登录记录。大概的流程是这样的:

1.客户端使用用户名跟密码请求登录

2.服务端收到请求,去验证用户名与密码

3.验证成功后,服务端会签发一个 Token,再把这个 Token 发送给客户端

4.客户端收到 Token 以后可以把它存储起来,比如放在 Cookie 里或者 Local Storage 里

5.客户端每次向服务端请求资源的时候需要带着服务端签发的 Token

6.服务端收到请求,然后去验证客户端请求里面带着的 Token,如果验证成功,就向客户端返回请求的数据

二、定义

token:服务端生成的一串字符串,可以解决频繁登录的问题它作为客户端进行请求的一个令牌:
第一次登录后,服务器生成一个token返回给客户端;客户端只需要带上token来请求数据即可,无需再次带上用户名和密码;可以有效减轻服务器的压力,减少频繁的查询数据库,使服务器更加健壮。

三、token的组成部分

token分为三部分来定义:

1 .表头:Header是一个json对象,存储元数据

{
"alg":"HS256",
"typ":"JWT"
}

alg:是签名的算法名称(algorithm),默认是HMAC SHA);

type属性表示这个令牌(token)的类型(type),JWT令牌统一写成JWT。

2.负载:Payload是一个json对象。存放传递的数据,数据分为Public和Private。

Public是JWT中规定的一些字段,可以自己选择使用。


iss(issuer):签发人

exp(expiration time):过期时间

sub(subject):该JWT所面向的用户

aud(audience):受众,接受该JWT的一方

nbf(not before):生效时间

iat(Issued At):签发时间

jti(JWT ID):编号
Private是自己定义的字段

{

“role":经理,
"name":张凡,
"id":23455
}

Play默认是没有加密的,以上数据都是明文传输的,所以最好不要存放敏感数据。前两部分数据都是json对象使用的是base64URL编码,翻译为字符串。

3.Signature:签名。签名是对Header和Payload两部分的签名,目的是为了防止数据被篡改

HMACSHA256(
    base64UrlEncoder(header)+"."+
    base64UrlENcode(paylosd),
    secret)

签名算法:先指定一个secret密匙,把base64URL的header,base64RL的payload和secret秘匙 使用HNAC SHA256生成签名字符串。

最后把三个部分的拼成一个字符串,每个部分之间用点(.)分隔,就可以返回给用户。

四、token 使用

1.生成token字符串

    private long time=1000*60*60*24;
    private String signature="admin";
    @Test
    public void jwt(){
        JwtBuilder jwtBuilder= Jwts.builder();
//        jwt三部分组成,Header,Payload,Signature
        String jwtToken=jwtBuilder
                //header
                .setHeaderParam("typ","JWT")
                .setHeaderParam("alg","HS256")
                //payload
                .claim("username","tom")
                .claim("role","admin")
                .setSubject("admin-test")
                .setExpiration(new Date(System.currentTimeMillis()+time))
                .setId(UUID.randomUUID().toString())
               //Signature
                .signWith(SignatureAlgorithm.HS256,signature)
                //拼接字符串
                .compact();
        System.out.println(jwtToken);
    }

2.对生成的token进行验证

  @Test
    public void parse(){
        String token="eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VybmFtZSI6InRvbSIsInJvbGUiOiJhZG1pbiIsInN1YiI6ImFkbWluLXRlc3QiLCJleHAiOjE2NDA4NDY5NTAsImp0aSI6ImEwM2YwOGQ2LTFhNWItNGZkNi1hODQxLWM1YWIwYTUxZTZmNyJ9.Xv_ntmDtItl6_k_U40DqqKceDkhaYedRJ4h7Opr1wTE";
        JwtParser jwtParser=Jwts.parser();
        Jws claimsJws=jwtParser.setSigningKey(signature).parseClaimsJws(token);
        Claims claims =claimsJws.getBody();
        System.out.println(claims.get("username"));
        System.out.println(claims.getSubject());
        System.out.println(claims.getExpiration());
    }

五、欢迎大家关注我

微信公众号:杨同学的编程生活
 

你可能感兴趣的:(Java,java,后端,spring,boot)