0


JWT原理&多语言实现

JWT基础概念

JWT是json web token缩写。它将用户信息加密到token里,服务器不保存任何用户信息。服务器通过使用保存的密钥验证token的正确性,只要正确即通过验证。基于token的身份验证可以替代传统的cookie+session身份验证方法。

代码来自网络,亲测有效,所以记录一下

JWT由三个部分组成:

header.payload.signature

header部分

该字段为json格式,alg字段指生成signature的算法,默认值为

HS256

,typ默认值为JWT

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

payload

该字段为json格式,表明用户身份的数据,可以根据业务需求自行定义

{"username":"admin",//该JWT的签发者"exp":1535974630,//过期时间,系统当前时间*}

signature部分:

签名算法,一般为HS256,其他的算法怎么整,具体长啥样儿我也不知道,没有找到,郁闷

jwt生成详解:

以加密方式为

HS256

为例

header进行base64UrlEncode加密后的字符串–字符串1

base64UrlEncode(header)

payload的内容进行base64UrlEncode加密后的字符串–字符串2

base64UrlEncode(payload)

字符串1+'.'+字符串2

拼接成一个新的字符串–字符串3

base64UrlEncode(header)+’.’+base64UrlEncode(payload)

通过header中的指定的算法来对字符串3 和一个密钥secret进行

HMacSHA256()

进行加密得到一个新的字符串就是jwt的主要内容

//java  //HMACSHA256签名   https://jwt.io/introduction  中HMACSHAHMacSHA256(base64UrlEncode(header)+'.'+base64UrlEncode(payload)+ secret)

实现

python代码实现

主要是用pyjwt这个包来实现加解密

# pip3 install pyjwtimport jwt
import datetime
from jwt import exceptions

JWT_SALT ='ashlkdjfhoawhe;kfjnasdlkfjlasdhfoiuahsdvlajksnd'defcreate_token(payload, timeout=20):"""
    :param payload:  例如:{'user_id':1,'username':'sinmu'}用户信息
    :param timeout: token的过期时间,默认20s
    :return:
    """
    headers ={'typ':'jwt','alg':'HS256'}
    payload['exp']= datetime.datetime.utcnow()+ datetime.timedelta(seconds=timeout)
    tmp = jwt.encode(payload=payload, key=JWT_SALT, algorithm="HS256", headers=headers)
    result = tmp.encode('utf-8')return result

defparse_payload(token):"""
    对token进行和发行校验并获取payload
    :param token:
    :return:
    """
    result ={'status':False,'data':None,'error':None}try:
        verified_payload = jwt.decode(token, JWT_SALT, algorithms="HS256")
        result['status']=True
        result['data']= verified_payload
    except exceptions.ExpiredSignatureError:
        result['error']='token已失效'except jwt.DecodeError:
        result['error']='token认证失败'except jwt.InvalidTokenError:
        result['error']='非法的token'return result

if __name__ =='__main__':
    token = create_token({'uid':1,'username':'sinmu'},3).decode('utf-8')
    res = parse_payload(token)print(res)

Java实现jwt

import io.jsonwebtoken.*;import java.util.Date;publicclassJwtUtils{privatelong expire=7200;private String secret="dwhidhkwhdkdiwhd232323dwdadwdw2a";private String header="Authorization";// 生成jwtpublic String generateToken(String username){

        Date nowDate =newDate();
        Date expireDate =newDate(nowDate.getTime()+1000* expire);return Jwts.builder().setHeaderParam("typ","JWT").setSubject(username).setIssuedAt(nowDate).setExpiration(expireDate)// 两小时过期.signWith(SignatureAlgorithm.HS512, secret).compact();}// 解析jwtpublic Claims getClaimByToken(String jwt){try{return Jwts.parser().setSigningKey(secret).parseClaimsJws(jwt).getBody();}catch(Exception e){return null;}}// jwt是否过期publicbooleanisTokenExpired(Claims claims){return claims.getExpiration().before(newDate());}}

PHP实现JWT

<?php/**
 * PHP实现jwt
 */classJwt{//头部privatestatic$header=array('alg'=>'HS256',//生成signature的算法'typ'=>'JWT'//类型);//使用HMAC生成信息摘要时所使用的密钥privatestatic$key='123456';/**
     * 获取jwt token
     * @param array $payload jwt载荷   格式如下非必须
     * [
     *  'iss'=>'jwt_admin',  //该JWT的签发者
     *  'iat'=>time(),  //签发时间
     *  'exp'=>time()+7200,  //过期时间
     *  'nbf'=>time()+60,  //该时间之前不接收处理该Token
     *  'sub'=>'www.admin.com',  //面向的用户
     *  'jti'=>md5(uniqid('JWT').time())  //该Token唯一标识
     * ]
     * @return bool|string
     */publicstaticfunctiongetToken(array$payload){if(is_array($payload)){$base64header=self::base64UrlEncode(json_encode(self::$header,JSON_UNESCAPED_UNICODE));$base64payload=self::base64UrlEncode(json_encode($payload,JSON_UNESCAPED_UNICODE));$token=$base64header.'.'.$base64payload.'.'.self::signature($base64header.'.'.$base64payload,self::$key,self::$header['alg']);return$token;}else{returnfalse;}}/**
     * 验证token是否有效,默认验证exp,nbf,iat时间
     * @param string $Token 需要验证的token
     * @return bool|string
     */publicstaticfunctionverifyToken(string $Token){$tokens=explode('.',$Token);if(count($tokens)!=3)returnfalse;list($base64header,$base64payload,$sign)=$tokens;//获取jwt算法$base64decodeheader=json_decode(self::base64UrlDecode($base64header),JSON_OBJECT_AS_ARRAY);if(empty($base64decodeheader['alg']))returnfalse;//签名验证if(self::signature($base64header.'.'.$base64payload, self::$key,$base64decodeheader['alg'])!==$sign)returnfalse;$payload=json_decode(self::base64UrlDecode($base64payload),JSON_OBJECT_AS_ARRAY);//签发时间大于当前服务器时间验证失败if(isset($payload['iat'])&&$payload['iat']>time())returnfalse;//过期时间小宇当前服务器时间验证失败if(isset($payload['exp'])&&$payload['exp']<time())returnfalse;//该nbf时间之前不接收处理该Tokenif(isset($payload['nbf'])&&$payload['nbf']>time())returnfalse;return$payload;}/**
     * base64UrlEncode   https://jwt.io/  中base64UrlEncode编码实现
     * @param string $input 需要编码的字符串
     * @return string
     */privatestaticfunctionbase64UrlEncode(string $input){returnstr_replace('=','',strtr(base64_encode($input),'+/','-_'));}/**
     * base64UrlEncode  https://jwt.io/  中base64UrlEncode解码实现
     * @param string $input 需要解码的字符串
     * @return bool|string
     */privatestaticfunctionbase64UrlDecode(string $input){$remainder=strlen($input)%4;if($remainder){$addlen=4-$remainder;$input.=str_repeat('=',$addlen);}returnbase64_decode(strtr($input,'-_','+/'));}/**
     * HMACSHA256签名   https://jwt.io/  中HMACSHA256签名实现
     * @param string $input 为base64UrlEncode(header).".".base64UrlEncode(payload)
     * @param string $key
     * @param string $alg   算法方式
     * @return mixed
     */privatestaticfunctionsignature(string $input, string $key, string $alg='HS256'){$alg_config=array('HS256'=>'sha256');# HS256=> HASH_HMAC(SHA256,string,secret,true)return self::base64UrlEncode(hash_hmac($alg_config[$alg],$input,$key,true));}}//测试和官网是否匹配begin$payload=array('uid'=>1,'name'=>'sinmu','iat'=>1516239022);$jwt=newJwt;$token=$jwt->getToken($payload);echo"<pre>";echo$token;//对token进行验证签名$getPayload=$jwt->verifyToken($token);echo"<br><br>";var_dump($getPayload);echo"<br><br>";//测试和官网是否匹配end//自己使用测试begin$payload_test=array('iss'=>'admin','iat'=>time(),'exp'=>time()+7200,'nbf'=>time(),'sub'=>'www.admin.com','jti'=>md5(uniqid('JWT').time()));;$token_test=Jwt::getToken($payload_test);echo"<pre>";echo$token_test;//对token进行验证签名$getPayload_test=Jwt::verifyToken($token_test);echo"<br><br>";var_dump($getPayload_test);echo"<br><br>";//自己使用时候end
标签: JWT 认证 字符串

本文转载自: https://blog.csdn.net/qq_41834798/article/details/116573216
版权归原作者 SinMu-L 所有, 如有侵权,请联系我们删除。

“JWT原理&多语言实现”的评论:

还没有评论