Knowledge summary - principle and use of 05 token

1. token has two main functions:
(1) Prevent form from being submitted repeatedly (set the time limit)

Principle: generate a unique random identification number on the server side. The technical term is Token. At the same time, save the Token in the Session domain of the current user.

Then the Token is sent to the Form form of the client, and the hidden field is used to store the Token in the Form form. When the Form is submitted, it is submitted to the server together with the Token,

Then judge whether the Token submitted by the client is consistent with the Token generated by the server on the server side. If it is inconsistent, it is repeated submission,

At this point, the server can not process the repeatedly submitted form. If it is the same, the form submission will be processed. After processing, the ID stored in the Session field of the current user will be cleared

(2) Used for authentication (after logging in to obtain the token, judge whether the token with the request is the same)

Principle: using Token based authentication method, there is no need to store the user's login record in the server. The general process is as follows:

Client requests login with user name and password
The server receives the request to verify the user name and password
After the verification is successful, the server will issue a Token and send the Token to the client
After receiving the Token, the client can store it in a Cookie or Local Storage
Each time the client requests resources from the server, it needs to bring the Token issued by the server
The server receives the request and verifies the Token in the client's request. If the verification is successful, it returns the requested data to the client

2. token verification process
1. Register the user information, and the front end will send the user name and password to the back end

2. The back end receives the parameters and stores them in the database, and then generates a token to return to the front end (token is mainly used to verify the user's login status)
3. The front end receives the token returned by the back end and stores it in sessionStorage
4. The front-end implements login, transmits the user name and password to the background, and brings the token.
5. The back end returns a new token to the front end, and verifies whether the user name and password are correct, and returns the result to the front end.
6. The front end receives the message returned by the back end, performs the corresponding operation, and stores the token in the sessionStorage.
7. After the login is successful, jump to the home page and request the data of the home page to come back and take the token to the back end.
8. The back end receives the token from the front end and judges whether it is valid. If it is valid, it will return the corresponding data information to the front-end; if it is invalid, it will return "login failed, login similar fields again".
9. The front end receives the message returned by the back end and performs the corresponding operation.

3. Code parsing
//Add user information to token. User information may be used after token verification

type MyClaims struct {
   UserName string `json:"user_name"`
 UserId   string `json:"user_id"`

// Generate token according to user name and pass it to client
func GenToken(username string, userId string) (token string) {
   myClaims := MyClaims{
         NotBefore: int64(time.Now().Unix()),
         ExpiresAt: int64(time.Now().Unix() + 86400), // 86400 for one day
 Issuer:    "duxiaoman",
   key := beego.AppConfig.String("TokenSignKey")
   ss := jwt.NewWithClaims(jwt.SigningMethodHS256, myClaims)
   token, _ = ss.SignedString([]byte(key))
   return token
//beego.AppConfig.String()Read configuration information

//The method to read configuration parameters in different modes is "mode:: configuration parameter name", for example: beego.AppConfig.String("dev::mysqluser").

//Extract user information if the token is parsed to determine whether it is valid or not

func ValidateTokenMiddleware(tokenString string) (username string, userId string, isOk bool) {
   olog.Debug("start validate token")
   token, err := jwt.ParseWithClaims(tokenString, &MyClaims{}, func(token *jwt.Token) (interface{}, error) {
      return []byte(beego.AppConfig.String("TokenSignKey")), nil
   claims, ok := token.Claims.(*MyClaims)
   if ok && token.Valid {
      username = claims.UserName
      userId = claims.UserId
      isOk = ok
      olog.Debug("token is validate")
   } else {
      olog.Debug("token is not validate ,err is ", err)

//Other operations after login, whether the user requesting authentication has a token

var AuthFilter = func(ctx *context.Context) {
   if ctx.Request.RequestURI != "/fsg-resource/ui/auth/login" {
      olog.Debug("start auth request")
      token := ctx.Request.Header.Get("Authorization")
      if token != "" {
         username, userId, isOk := ValidateTokenMiddleware(token)
         olog.Debug("request is ok ,username is ", username)
         if isOk {
            ctx.Input.SetData("username", username)
            ctx.Input.SetData("userID", userId)
         if !isOk {
            olog.Debug("request token is not validate")
            ctx.Redirect(401, "/401")
      } else {
         olog.Debug("request token is not exists")
         ctx.Redirect(401, "/401")

URI, a uniform resource identifier, is used to uniquely identify a resource.

The URL is a uniform resource locator, a uniform resource locator. It is a specific URI, that is, the URL can be used to identify a resource, and also indicates how to locate the resource.

Get token: Token: = CTX. Request. Header. Get ("Authorization")
token is usually placed in Authorization field in HTTP request
Get user information according to Token: username, userid, isok: = validatetokenmiddleware (token)

ctx.Input.SetData("username", username)
GetData is used to get data from a filter in the controller. It allows you to pass values that are not just strings.

Get the value of the data in the input from the Beego document: GetData

The set value of the data in the SetData input. GetData and SetData are used to pass data from the filter to the controller

Complete token code

//Authentication ticket, return token correctly

func AuthTicket(ticket string, nexturl string) (userInfo map[string]interface{}, err error) {
   olog.Debug("Authentication ticket")
   url := fmt.Sprintf("%s?service=%s?next=%s&ticket=%s&appKey=%s", global.UUAPAuthUrl, global.ServiceUrl, nexturl, ticket, global.UUAPAppKey)
   resp, err := http.Get(url)
   if err == nil {
      defer resp.Body.Close()
      body, err := ioutil.ReadAll(resp.Body)
      username, err := parserXml(string(body))
      if err == nil {
         // Get username to generate token
 userInfo = UserAuth(username)
         token := GenToken(username, strconv.Itoa(userInfo["userID"].(int)))
         userInfo["token"] = token
         olog.Debug("Authentication ticket Success", ticket)

The principle of ctx.Input.SetData() and c.Ctx.Input.GetData()

ctx.Input.SetData() one to one relationship

After the user authenticates, there will be a token. Each request will take the token. After the token is parsed, there will be the user information inside.

Each request will first verify the token. If the verification is successful, the user name of setData will be set, and then the value can be got in the controller.

Published 10 original articles, won praise 0, visited 72
Private letter follow

Keywords: Session JSON Unix Database

Added by mhouldridge on Sun, 23 Feb 2020 08:16:27 +0200