JWT实现基于token的鉴权 JWT实现基于token的鉴权

JWT实现基于token的鉴权

一.介绍

  1.  1.JSON Web Token,简称JWT,本质是一个token,是一种紧凑的URL安全方法,用于在网络通信的双方之间传递。
  2.  2.一般放在HTTP的headers 参数里面的authorization里面,值的前面加Bearer关键字和空格。
  3.  3.主要用于身份认证和信息交换
  4.  4.由三部分组成,用英文句点连接(.),例如:xxxxxx.yyyyyy.zzzzzz

二.JWT的结构:JWT是三段(header.payload.signature)由小数点组成的字符串

a)header:头部用于描述关于JWT的基本的信息(如:类型,签名算法):

[plain]  view plain  copy
  1. <span style="color:rgb(0,0,0);"><span style="font-size:14px;">{  
  2.   "alg": "HS256",  
  3.   "typ": "JWT"  
  4. }</span></span>  

 b)payload:包含claims(有三种:标准中注册的声明,公共声明,私有声明)的消息体:

 标准中注册的声明,建议但不强制使用:

  >iss: jwt的签发者
  >sub: jwt所面向的用户
  >aud: 接收该jwt的一方 
  > exp: jwt的过期时间
  > nbf: 在该时间之前,该jwt都是不可用的
  > iat:jwt签发时间
  > jti:jwt的ID

[plain]  view plain  copy
  1. <span style="color:rgb(0,0,0);"><span style="font-size:14px;">{  
  2.   "sub": "1234567890",  
  3.   "name": "John Doe",  
  4.   "admin": true  
  5. }</span></span>  
 c)Signature:验证JWT有没有被篡改


 生成过程:

 第一部分:将header的json对象进行base64编码

 第二部分:将payload的json对象进行base64编码

  第三部分:将拼接好的前两部分使用签名算法加密

 更详细的介绍:

 https://jwt.io/introduction/

 https://tools.ietf.org/html/draft-ietf-oauth-json-web-token-32

 (2)验证流程:

  1.  1.首次登录:提交用户名密码 
  2.  2.密码验证:通过后根据用户信息生成JWT
  3.  3.返回JWT:把JWT返回客户端,设置cookie或者设置到http请求头的Authorization中(一般是在请求头里加入Authorization并加上Bearer标注)
  4.  4.带JWT请求:每次访问服务器的时候都携带JWT,服务器根据JWT进行验证是否被篡改,没有的话获取信息

二.简单使用(使用jwt-go:https://github.com/dgrijalva/jwt-go

[plain]  view plain  copy
  1. <span style="font-size:14px;">//密匙  
  2. const (  
  3.     SecretKey = "welcome"  
  4. )  
  5. //错误处理  
  6. func fatal(err error) {  
  7.     if err != nil {  
  8.         log.Fatal(err)  
  9.     }  
  10. }  
  11. //用户凭证  
  12. type UserCredentials struct {  
  13.     Username string `json:"username"`  
  14.     Password string `json:"password"`  
  15. }  
  16.   
  17. type User struct {  
  18.     ID       int    `json:"id"`  
  19.     Name     string `json:"name"`  
  20.     Username string `json:"username"`  
  21.     Password string `json:"password"`  
  22. }  
  23.   
  24. type Response struct {  
  25.     Data string `json:"data"`  
  26. }  
  27.   
  28. type Token struct {  
  29.     Token string `json:"token"`  
  30. }  
  31.   
  32. func StartServer() {  
  33.   
  34.     http.HandleFunc("/login", LoginHandler)  
  35.   
  36.     http.Handle("/resource", negroni.New(  
  37.         negroni.HandlerFunc(ValidateTokenMiddleware),  
  38.         negroni.Wrap(http.HandlerFunc(ProtectedHandler)),  
  39.     ))  
  40.   
  41.     log.Println("Now listening...")  
  42.     http.ListenAndServe(":8080", nil)  
  43. }  
  44.   
  45. func main() {  
  46.     StartServer()  
  47. }  
  48. //业务处理  
  49. func ProtectedHandler(w http.ResponseWriter, r *http.Request) {  
  50.   
  51.     response := Response{"Gained access to protected resource"}  
  52.     JsonResponse(response, w)  
  53.   
  54. }  
  55. //登录获取token  
  56. func LoginHandler(w http.ResponseWriter, r *http.Request) {  
  57.   
  58.     var user UserCredentials  
  59.     err := json.NewDecoder(r.Body).Decode(&user)  
  60.   
  61.     if err != nil {  
  62.         w.WriteHeader(http.StatusForbidden)  
  63.         fmt.Fprint(w, "Error in request")  
  64.         return  
  65.     }  
  66.   
  67.     if strings.ToLower(user.Username) != "someone" {  
  68.         if user.Password != "password" {  
  69.             w.WriteHeader(http.StatusForbidden)  
  70.             fmt.Println("Error logging in")  
  71.             fmt.Fprint(w, "Invalid credentials")  
  72.             return  
  73.         }  
  74.     }  
  75.   
  76.     token := jwt.New(jwt.SigningMethodHS256)  
  77.     claims := make(jwt.MapClaims)  
  78.     claims["exp"] = time.Now().Add(time.Hour * time.Duration(1)).Unix()  
  79.     claims["iat"] = time.Now().Unix()  
  80.     token.Claims = claims  
  81.   
  82.     if err != nil {  
  83.         w.WriteHeader(http.StatusInternalServerError)  
  84.         fmt.Fprintln(w, "Error extracting the key")  
  85.         fatal(err)  
  86.     }  
  87.   
  88.     tokenString, err := token.SignedString([]byte(SecretKey))  
  89.     if err != nil {  
  90.         w.WriteHeader(http.StatusInternalServerError)  
  91.         fmt.Fprintln(w, "Error while signing the token")  
  92.         fatal(err)  
  93.     }  
  94.   
  95.     response := Token{tokenString}  
  96.     JsonResponse(response, w)  
  97.   
  98. }  
  99. //验证token  
  100. func ValidateTokenMiddleware(w http.ResponseWriter, r *http.Request, next http.HandlerFunc) {  
  101.   
  102.     token, err := request.ParseFromRequest(r, request.AuthorizationHeaderExtractor,  
  103.         func(token *jwt.Token) (interface{}, error) {  
  104.             return []byte(SecretKey), nil  
  105.         })  
  106.   
  107.     if err == nil {  
  108.         if token.Valid {  
  109.             next(w, r)  
  110.         } else {  
  111.             w.WriteHeader(http.StatusUnauthorized)  
  112.             fmt.Fprint(w, "Token is not valid")  
  113.         }  
  114.     } else {  
  115.         w.WriteHeader(http.StatusUnauthorized)  
  116.         fmt.Fprint(w, "Unauthorized access to this resource")  
  117.     }  
  118.   
  119. }  
  120.   
  121. func JsonResponse(response interface{}, w http.ResponseWriter) {  
  122.   
  123.     json, err := json.Marshal(response)  
  124.     if err != nil {  
  125.         http.Error(w, err.Error(), http.StatusInternalServerError)  
  126.         return  
  127.     }  
  128.   
  129.     w.WriteHeader(http.StatusOK)  
  130.     w.Header().Set("Content-Type", "application/json")  
  131.     w.Write(json)  
  132. }</span>  
 测试:




转自https://blog.csdn.net/simatongming/article/details/79102597

一.介绍

  1.  1.JSON Web Token,简称JWT,本质是一个token,是一种紧凑的URL安全方法,用于在网络通信的双方之间传递。
  2.  2.一般放在HTTP的headers 参数里面的authorization里面,值的前面加Bearer关键字和空格。
  3.  3.主要用于身份认证和信息交换
  4.  4.由三部分组成,用英文句点连接(.),例如:xxxxxx.yyyyyy.zzzzzz

二.JWT的结构:JWT是三段(header.payload.signature)由小数点组成的字符串

a)header:头部用于描述关于JWT的基本的信息(如:类型,签名算法):

[plain]  view plain  copy
  1. <span style="color:rgb(0,0,0);"><span style="font-size:14px;">{  
  2.   "alg": "HS256",  
  3.   "typ": "JWT"  
  4. }</span></span>  

 b)payload:包含claims(有三种:标准中注册的声明,公共声明,私有声明)的消息体:

 标准中注册的声明,建议但不强制使用:

  >iss: jwt的签发者
  >sub: jwt所面向的用户
  >aud: 接收该jwt的一方 
  > exp: jwt的过期时间
  > nbf: 在该时间之前,该jwt都是不可用的
  > iat:jwt签发时间
  > jti:jwt的ID

[plain]  view plain  copy
  1. <span style="color:rgb(0,0,0);"><span style="font-size:14px;">{  
  2.   "sub": "1234567890",  
  3.   "name": "John Doe",  
  4.   "admin": true  
  5. }</span></span>  
 c)Signature:验证JWT有没有被篡改


 生成过程:

 第一部分:将header的json对象进行base64编码

 第二部分:将payload的json对象进行base64编码

  第三部分:将拼接好的前两部分使用签名算法加密

 更详细的介绍:

 https://jwt.io/introduction/

 https://tools.ietf.org/html/draft-ietf-oauth-json-web-token-32

 (2)验证流程:

  1.  1.首次登录:提交用户名密码 
  2.  2.密码验证:通过后根据用户信息生成JWT
  3.  3.返回JWT:把JWT返回客户端,设置cookie或者设置到http请求头的Authorization中(一般是在请求头里加入Authorization并加上Bearer标注)
  4.  4.带JWT请求:每次访问服务器的时候都携带JWT,服务器根据JWT进行验证是否被篡改,没有的话获取信息

二.简单使用(使用jwt-go:https://github.com/dgrijalva/jwt-go

[plain]  view plain  copy
  1. <span style="font-size:14px;">//密匙  
  2. const (  
  3.     SecretKey = "welcome"  
  4. )  
  5. //错误处理  
  6. func fatal(err error) {  
  7.     if err != nil {  
  8.         log.Fatal(err)  
  9.     }  
  10. }  
  11. //用户凭证  
  12. type UserCredentials struct {  
  13.     Username string `json:"username"`  
  14.     Password string `json:"password"`  
  15. }  
  16.   
  17. type User struct {  
  18.     ID       int    `json:"id"`  
  19.     Name     string `json:"name"`  
  20.     Username string `json:"username"`  
  21.     Password string `json:"password"`  
  22. }  
  23.   
  24. type Response struct {  
  25.     Data string `json:"data"`  
  26. }  
  27.   
  28. type Token struct {  
  29.     Token string `json:"token"`  
  30. }  
  31.   
  32. func StartServer() {  
  33.   
  34.     http.HandleFunc("/login", LoginHandler)  
  35.   
  36.     http.Handle("/resource", negroni.New(  
  37.         negroni.HandlerFunc(ValidateTokenMiddleware),  
  38.         negroni.Wrap(http.HandlerFunc(ProtectedHandler)),  
  39.     ))  
  40.   
  41.     log.Println("Now listening...")  
  42.     http.ListenAndServe(":8080", nil)  
  43. }  
  44.   
  45. func main() {  
  46.     StartServer()  
  47. }  
  48. //业务处理  
  49. func ProtectedHandler(w http.ResponseWriter, r *http.Request) {  
  50.   
  51.     response := Response{"Gained access to protected resource"}  
  52.     JsonResponse(response, w)  
  53.   
  54. }  
  55. //登录获取token  
  56. func LoginHandler(w http.ResponseWriter, r *http.Request) {  
  57.   
  58.     var user UserCredentials  
  59.     err := json.NewDecoder(r.Body).Decode(&user)  
  60.   
  61.     if err != nil {  
  62.         w.WriteHeader(http.StatusForbidden)  
  63.         fmt.Fprint(w, "Error in request")  
  64.         return  
  65.     }  
  66.   
  67.     if strings.ToLower(user.Username) != "someone" {  
  68.         if user.Password != "password" {  
  69.             w.WriteHeader(http.StatusForbidden)  
  70.             fmt.Println("Error logging in")  
  71.             fmt.Fprint(w, "Invalid credentials")  
  72.             return  
  73.         }  
  74.     }  
  75.   
  76.     token := jwt.New(jwt.SigningMethodHS256)  
  77.     claims := make(jwt.MapClaims)  
  78.     claims["exp"] = time.Now().Add(time.Hour * time.Duration(1)).Unix()  
  79.     claims["iat"] = time.Now().Unix()  
  80.     token.Claims = claims  
  81.   
  82.     if err != nil {  
  83.         w.WriteHeader(http.StatusInternalServerError)  
  84.         fmt.Fprintln(w, "Error extracting the key")  
  85.         fatal(err)  
  86.     }  
  87.   
  88.     tokenString, err := token.SignedString([]byte(SecretKey))  
  89.     if err != nil {  
  90.         w.WriteHeader(http.StatusInternalServerError)  
  91.         fmt.Fprintln(w, "Error while signing the token")  
  92.         fatal(err)  
  93.     }  
  94.   
  95.     response := Token{tokenString}  
  96.     JsonResponse(response, w)  
  97.   
  98. }  
  99. //验证token  
  100. func ValidateTokenMiddleware(w http.ResponseWriter, r *http.Request, next http.HandlerFunc) {  
  101.   
  102.     token, err := request.ParseFromRequest(r, request.AuthorizationHeaderExtractor,  
  103.         func(token *jwt.Token) (interface{}, error) {  
  104.             return []byte(SecretKey), nil  
  105.         })  
  106.   
  107.     if err == nil {  
  108.         if token.Valid {  
  109.             next(w, r)  
  110.         } else {  
  111.             w.WriteHeader(http.StatusUnauthorized)  
  112.             fmt.Fprint(w, "Token is not valid")  
  113.         }  
  114.     } else {  
  115.         w.WriteHeader(http.StatusUnauthorized)  
  116.         fmt.Fprint(w, "Unauthorized access to this resource")  
  117.     }  
  118.   
  119. }  
  120.   
  121. func JsonResponse(response interface{}, w http.ResponseWriter) {  
  122.   
  123.     json, err := json.Marshal(response)  
  124.     if err != nil {  
  125.         http.Error(w, err.Error(), http.StatusInternalServerError)  
  126.         return  
  127.     }  
  128.   
  129.     w.WriteHeader(http.StatusOK)  
  130.     w.Header().Set("Content-Type", "application/json")  
  131.     w.Write(json)  
  132. }</span>  
 测试:




转自https://blog.csdn.net/simatongming/article/details/79102597

猜你喜欢

转载自blog.csdn.net/weixin_40592935/article/details/80824776