为什么需要token?在后台管理系统中,我们通常使用cookie-session进行认证。如何通过cookie和session认证(nodejs/koa)但是这种方式存在以下问题,比如cookie的容量对于浏览器和app来说太小了端发送http请求时携带cookie会有差异。分布式系统和服务器集群保证如何保证sessionId相同。基于以上问题,采用token方式,token的认证不受浏览器或app端的限制,具有通用性和安全性。两者都更强。数据格式通常用于实现token认证方式jwt,即jsonwebtoken。jwt的格式,比如xxx.yyy.zzzxxx,用来描述使用什么样的加密方式。yyy部分是携带的数据,比如id,name,通常还会携带iat(issueat)发布时间和exp(expirationtime)过期时间,用于判断token是否在有效期内验证。上面的xxx和yyy转成base64编码的json数据zzz是对xxx.yyy加一个key加密,加密方式在header中。Forexample,inthefigureabove,theencryptionmethodusedbytheservertogeneratetokenisHS256,thecontenttobesavedisidandname,andthekeyis123456headerpart{"alg":"HS256","typ":"JWT"}//base64encoding结果:eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9playload部分{"id":1,"name":"Alice","iat":1630814528619,"exp":1630816048023}//base64编码结果:eyJpZCI6MSwibmFtZSI6IkFsaWNlIiwiaWF0IjoxNjMwODE0NTI4NjE5LCJleHAiOjE2MzA4MTYwNDgwMjN9signature部分//加密结果为:B2df_qYbivZcjpJ_QtIyRu4ts6n_pwxlSQl41Bpsxz8最后的结果就是把三部分拼接起来,以.分隔eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6MSwibmFtZSI6IkFsaWNlIiwiaWF0IjoxNjMwODE0NTI4NjE5LCJleHAiOjE2MzA4MTYwNDgwMjN9.B2df_qYbivZcjpJ_QtIyRu4ts6n_pwxlSQl41Bpsxz8可以看到jwt的header和payload都是用base64进行编码的,也可解码,所以并不能存放重要信息,而jwt数据的传递也不是为了加密Importantinformation,thesignaturepartofjwtneedstobeencryptedbyakey.Aslongasthekeyisnotleaked,theidentitywillnotbeeasilyforged.jwt的使用方法可以在客户端向服务端发送请求的时候携带,放在header中,使用授权域,使用公钥私钥对称加密算法的Bearer方式,只用一个key即可encryptanddecrypt非对称加密算法,公钥用于加密,私钥用于解密。openssl可以生成公钥和私钥//生成公钥genrsa-outprivate.key2048//生成私钥rsa-inprivate.key-puout-outpublic.key分别生成public.key和private.key文件。服务器如何认证?用户登录成功后,服务器返回一个token。使用Koa作为演示。constjwt=require("jsonwebtoken")constPRIVATE_KEY=fs.readFileSync('./private.key')constuser={id:1,name:'kiki'}consttoken=jwt.sign(user,PRIVATE_KEY,{expiresIn:10,//unitsalgorithm:"RS256"})client将header中的authorization携带token数据,服务端验证token的有效性和正确性constPUBLIC_KEY=fs.readFileSync('./public.key')constauthorization=ctx.headers.authorizationconsttoken=authorization.replace("Bearer","")//失败会直接报错,所以需要抓取try{constresult=jwt.verify(token,PUBLIC_KEY,{algorithms:["RS256"]})//得到的信息是{id:1,name:'kiki',iat:'',exp:''}}catch(error){}
