JSON Web Token Getting Started Guide

Cross-domain authentication problem

Internet services can not do without user authentication. The general process is this:

  1. User sends the username and password to the server.
  2. After the server is verified, in the current session (session) which holds the relevant data, such as user roles, login time, and so on.
  3. Session_id a server returns to the user, the user writes the Cookie.
  4. The user then every request will by Cookie, the session_id back to the server.
  5. Server receives session_id, find pre-stored data, therefore represents the user's identity.

The problem with this model is that, scalability (scaling) is not good. Stand-alone course, no problem, if it is a cluster of servers, or cross-domain service-oriented architecture, it requires data sharing session, each server can read the session.

For example, A and B sites sites are associated with a company's service. Now it requires, as long as the user in which a website login, and then visit another website will automatically log in, ask how to achieve?

  • One solution is to session data persistence, written to the database or other persistence layer. Various services receipt of the request, all requested data to the persistence layer. The advantage of this approach is obvious structure, the disadvantage is larger than engineering. Further, in case of hanging persistence, will single point of failure.
  • Another option is simply the server does not save session data, and all data is stored in the client, each request back to the server. JWT is a representative of this program.

What is JWT?

Json web token (JWT), is a statement in order to pass between the network application execution environment based on open standards JSON ((RFC 7519). The token is designed to be compact and safe, especially for single-distributed sites sign-on (SSO) scenario .JWT statements are typically used to provide and service providers transfer between the user identity is authenticated identity information in order to obtain resources from the server, you can also add some extra other business logic that must be statement information, the authentication token may be directly used, or may be encrypted.

JWT principle

After authentication server generates a JSON object after the signature, sent back to the user, the server session without saving any of the data. Thus bringing the server to become stateless, easy to implement extensions.

JWT usage scenarios

Here are two JWT application scenarios:

  1. Authentication: JWT This is the most common scenarios. When the user logs in successfully, then each request will bring JWT, allowing users access to authorized services and resources. Because of its small overhead cut is easy to use, is currently widely used in single sign-on (Single Sign On).
  2. Information exchange: JWT is a great way to exchange information between different organizations. Because JWT can be signed (for example, through a public / private key pair), you can be sure that the sender is, they say identity claims. In addition, the signature is calculated using the Header and Payload, you can verify that the content has been tampered with.

JWT data structure

Flattened form is made by JWT .three-part composition of the partition, they are:

  • Header
  • Payload
  • Signature

Therefore, a look JWT usually the following form:

xxxxx.yyyyy.zzzzz

Header

Head consists of two parts:

  • token type, i.e., the JWT;
  • Signature algorithm, such as HMAC SHA256 or RSA.

A Header example:

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

Subsequently, the above object is JSON by Base64Urlencoding a first portion of the JWT.

Payload

Load local storage is valid information. The name refers specifically to such goods carried on the aircraft, these effective information consists of three parts

  • Standard registration statement
  • Public Statement
  • Private statement

Standard registration statement:

  • iss: jwt issuer
  • sub: jwt for the user
  • aud: the receiving side jwt
  • exp: jwt expiration time, the expiration date must be greater than the issue of time
  • nbf: What time is defined before the jwt are not available.
  • iat: jwt the issue of time
  • jti: jwt unique identity, is mainly used as a one-time token, in order to avoid a replay attack.

Public statement:
public declarations can add any information, general information about the user to add the necessary information or other business needs, but is not recommended for sensitive information to add, because the part of the client can decrypt.

Private statement:
Private statement is a statement providers and consumers as common definition, is generally not recommended to store sensitive information, because base64 is decrypted symmetric, meaning that some of the information may be classified as plaintext.

A Payload example:

{
  "sub": "1234567890",
  "name": "John Doe",
  "admin": true
}

Subsequently, Payload will pass Base64Urlencoding a second portion of the JWT.

Signature

Create a signature need to use Header encoded, Payload encoded, keys, Header specified algorithm.

If you want to use HMAC SHA256 algorithm, the signature will be generated by:

HMACSHA256(
  base64UrlEncode(header) + "." +
  base64UrlEncode(payload),
  secret)

If you want more than the concept into practice, the tool can be provided by https://jwt.io/ play a game of JWT. As shown below:jwt.io

JWT's use

JWT client receives the server returns, which can be stored in Cookie, can also be stored in localStorage.
Thereafter, each time the client and server communications, must bring the JWT. You can put it inside Cookie sent automatically, but this can not be cross-domain, so a better approach is to put Authorization header field of the HTTP request inside.

Authorization: Bearer <token>

Another approach is that when cross-domain, JWT POST request to the data volume on the inside.

JWT several features

  • JWT default are not encrypted, but also can be encrypted. After generating the original Token, it can be re-encrypted with a key once.
  • JWT case without encryption, secret data can not be written to JWT.
  • JWT not only can be used for authentication, it can also be used to exchange information. Effective use of JWT, the number of server queries the database can be reduced.
  • JWT biggest drawback is that, because the server does not save session state, a token can not be abolished in the course of, or change the permissions of the token. That is, once issued JWT, will remain in effect until maturity, unless the server to deploy additional logic.
  • JWT itself contains authentication information, when disclosed, anyone can get all the permissions of the token. To reduce theft, JWT's validity should be set relatively short. For some of the more important rights, should once again to authenticate the user during use.
  • To reduce theft, JWT should not use the HTTP protocol transmission codes, to use the HTTPS protocol.

Sample Code

Go language version:

package util

import (
	"crypto/rsa"
	"crypto/x509"
	"encoding/pem"
	"errors"
	"fmt"
	"github.com/dgrijalva/jwt-go"
)

var ErrVerifyFailed = fmt.Errorf("verify failed")

//https://godoc.org/github.com/dgrijalva/jwt-go#example-New--Hmac
func CreateToken(claims jwt.MapClaims, privateKey []byte) (string, error) {
	token := jwt.NewWithClaims(jwt.SigningMethodRS512, claims)

	block, _ := pem.Decode(privateKey)
	if block == nil {
		return "", errors.New("private key error")
	}

	priv, err := x509.ParsePKCS8PrivateKey(block.Bytes)
	if err != nil {
		return "", err
	}
	return token.SignedString(priv)
}

//https://godoc.org/github.com/dgrijalva/jwt-go#example-Parse--Hmac
func VerifyToken(tokenString string, publicKey []byte) (jwt.MapClaims, error) {
	token, err := jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) {
		if _, ok := token.Method.(*jwt.SigningMethodRSA); !ok {
			return nil, fmt.Errorf("unexpected signing method: %v", token.Header["alg"])
		}

		if token.Header["alg"] != "RS512" {
			return nil, fmt.Errorf("unexpected siging alg: %v", token.Header["alg"])
		}

		block, _ := pem.Decode(publicKey)
		if block == nil {
			return nil, ErrVerifyFailed
		}

		pubInterface, err := x509.ParsePKIXPublicKey(block.Bytes)
		if err != nil {
			return nil, ErrVerifyFailed
		}

		pub := pubInterface.(*rsa.PublicKey)
		return pub, nil
	})

	if err != nil {
		return nil, ErrVerifyFailed
	}

	if claims, ok := token.Claims.(jwt.MapClaims); ok && token.Valid {
		return claims, nil
	}

	return nil, ErrVerifyFailed
}

Reference Source:

  1. https://jwt.io/introduction/
  2. https://www.jianshu.com/p/576dbf44b2ae
  3. https://www.ruanyifeng.com/blog/2018/07/json_web_token-tutorial.html
Published 345 original articles · won praise 374 · views 890 000 +

Guess you like

Origin blog.csdn.net/u011331383/article/details/103191664