This article describes how JSONWebTokens works. It has a good reference value. let's take a look at it below. This article mainly introduces the implementation principle of JSON Web Tokens. It has good reference value. let's take a look at it together with the small editor.
Preface
Recently, I was working on a transformation of a Python project and restructured the python project into a Java project. I encountered this knowledge point in the process and thought it was quite practical. so I came back from work and wrote this summary, we hope that the people behind will be able to learn from each other and avoid detours.
I. Advantages
JSON Web Tokens (jwt) is a security policy for rest interfaces. It has many advantages:
Cross-Origin resolution: This Token-based access policy can overcome the cross-origin issue of cookies.
The server can be horizontally scaled out without the need to store Sessions. tokens can be authenticated.
System decoupling: Token carries all user information, without binding a specific authentication scheme. you only need to know the encryption method and key for encryption and decryption, which is conducive to decoupling.
Prevents cross-site scripting attacks without cookie technology, so you do not need to consider the security of cross-site requests.
II. Principles
JSON Web Tokens format. jwt is a base64 encoded character sequence separated by dots. it consists of three parts: header, message body playload, and signature sign.
1. the Header of jwt is in json format:
{ "typ":"JWT", "alg":"HS256", "exp":1491066992916}
Here, typ is short for type, which indicates that the type is JWT, the encryption method declaration is HS256, and exp indicates the current time.
2. jwt message body Playload
{ "userid":"123456", "iss":"companyName"}
The specific fields of the message body can be customized and added according to business needs. you only need to obtain the value by using the key value of the field during decryption.
3. sign generation
Signature. the signature is generated by using base64url encoding for the header and playload respectively, followed '. 'connect the two encoded strings, and then combine the concatenated strings with the key for HMAC SHA-256 algorithm encryption, and finally base64 encoding again, this gets the signature sign. use '. 'After the connection, the entire JWT is generated.
III. verification overview
The entire jwt structure is composed of header. playload. sign connection, only sign is encrypted with a key, and all information can be directly obtained in header and playload, the function of sign is to verify whether the header and playload information has been tampered with. Therefore, jwt cannot protect data, but the above features can be well applied to permission authentication.
1. Encryption
For example, if you want to encrypt and verify the userid field, first assemble the json header and message body playload in the preceding format, and press header. playload is a string, and then the header is encrypted based on the key and HS256. playload gets the sign and the jwtToken is the header. playload. sign: The url in the http request carries a parameter to request authentication for the backend service.
2. decryption
The backend service verifies that jwtToken has the right to access the interface service for decryption and authentication. for example, to verify the visitor's userid, first
Split the string into three strings by "." and get the header, playload, and sign respectively. Then, set header. playload assembly with the key and HAMC SHA-256 algorithm for encryption and then get the new string and sign for comparison, if the same, it means that the data is not tampered with, and then retrieve the exp from the header to determine the survival, if the current period is exceeded, an empty string is returned. if the current period is exceeded, the userid value is returned.
IV. Sample code
1. encryption and decryption of python code
#!/usr/bin/env python# coding: utf-8from itsdangerous import BadTimeSignature, SignatureExpiredfrom itsdangerous import TimedJSONWebSignatureSerializer as SerializerAPP_SECRET_KEY="secret"MAX_TOKEN_AGE=1800token_generator = Serializer(APP_SECRET_KEY, expires_in=MAX_TOKEN_AGE)def generate_auth_token(userid): access_token = token_generator.dumps({"userid":userid}) return access_tokendef verify_token(token): try: user_auth = token_generator.loads(token) print type(token_generator) except SignatureExpired as e: raise e except BadTimeSignature as e: raise e return user_auth
2. encryption and decryption of java code
Package api. test. util; import java. io. unsupportedEncodingException; import java. security. invalidKeyException; import java. security. noSuchAlgorithmException; import javax. crypto. mac; import javax. crypto. secretKey; import javax. crypto. spec. secretKeySpec; import org. apache. commons. codec. binary. base64; import org. springframework. beans. factory. annotation. value; import org. springframework. stereotype. component; import lombok. extern. slf4j. slf4j; import net. sf. json. JSONObject;/*** jwt encryption and decryption implementation ** @ author zhengsc */@ Slf4jpublic class TokenUtil {private String ISSUER = "companyName "; // institution private String APP_SECRET_KEY = "secret"; // key private long MAX_TOKEN_AGE = 1800; // retention period/*** generate the accessToken of userId ** @ param userid * @ return */public String generateAccessToken (String userid) {JSONObject claims = new JSONObject (); claims. put ("iss", ISSUER); claims. put ("userid", userid); String accessToken = sign (claims, APP_SECRET_KEY); return accessToken ;} /*** the decryption program returns userid ** @ param token * @ return */public String verifyToken (String token) {String userid = ""; try {String [] splitStr = token. split ("\\. "); String headerAndClaimsStr = splitStr [0] + ". "+ splitStr [1]; String veryStr = signHmac256 (headerAndClaimsStr, APP_SECRET_KEY); // check whether the data is tampered with if (veryStr. equals (splitStr [2]) {String header = new String (Base64.decodeBase64 (splitStr [0]), "UTF-8"); JSONObject head = JSONObject. fromObject (header); long expire = head. getLong ("exp") * 1000L; long currentTime = System. currentTimeMillis (); if (currentTime <= expire) {// verify the validity period of accessToken String claims = new String (Base64.decodeBase64 (splitStr [1]), "UTF-8 "); JSONObject claim = JSONObject. fromObject (claims); userid = (String) claim. get ("userid") ;}} catch (UnsupportedEncodingException e) {log. error (e. getMessage (), e);} return userid ;} /*** jwt returns the assembly encryption result ** @ param claims * @ param appSecretKey * @ return */private String sign (JSONObject claims, String appSecretKey) {String headerAndClaimsStr = getHeaderAndClaimsStr (claims); String signed256 = signHmac256 (headerAndClaimsStr, appSecretKey); return headerAndClaimsStr + ". "+ signed256;}/*** concatenate request headers and declarations ** @ param claims * @ return */private String getHeaderAndClaimsStr (JSONObject claims) {JSONObject header = new JSONObject (); header. put ("alg", "HS256"); header. put ("typ", "JWT"); header. put ("exp", System. currentTimeMillis () + MAX_TOKEN_AGE * 1000L); String headerStr = header. toString (); String claimsStr = claims. toString (); String headerAndClaimsStr = Base64.encodeBase64URLSafeString (headerStr. getBytes () + ". "+ Base64.encodeBase64URLSafeString (claimsStr. getBytes (); return headerAndClaimsStr ;} /*** use SHA1 to encrypt headerAndClaimsStr to obtain sign ** @ param headerAndClaimsStr * @ param appSecretKey * @ return */private String signHmac256 (String headerAndClaimsStr, String appSecretKey) {SecretKey key = new SecretKeySpec (appSecretKey. getBytes (), "HmacSHA256"); String result = null; try {Mac mac; mac = Mac. getInstance (key. getAlgorithm (); mac. init (key); result = Base64.encodeBase64URLSafeString (mac. doFinal (headerAndClaimsStr. getBytes ();} catch (NoSuchAlgorithmException | InvalidKeyException e) {log. error (e. getMessage (), e) ;}return result ;}}
The above is a detailed description of how to implement JSON Web Tokens. For more information, see other related articles in the first PHP community!