<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ??一站式輕松地調用各大LLM模型接口,支持GPT4、智譜、豆包、星火、月之暗面及文生圖、文生視頻 廣告
                [TOC] ## 概述 最近要在http接口上加一個token認證,但是接口很多,有沒有一個省時省力的辦法來解決。token的使用流程是: 1. 用戶使用帳號密碼登陸到服務器 2. 服務器驗證登陸成功,根據帳號密碼生成token。把token返回給客戶端 3. 客戶端請求接口時需要帶上token。服務器需要驗證token。 接口是用golang的`net/http`庫寫的。為了實現目的,還需要添加的功能是: 1. 生成和解析token的方法; 2. 一個中間件,攔截請求,進行token認證,根據認證通是否過來決定是否繼續執行請求; `JWT`身份認證可以解決第一個問題,`mux.Router`的`Use`方法函數可以作為一個中間件, 攔截請求。 ```golang func (r *Router) Use(mwf ...MiddlewareFunc) { for _, fn := range mwf { r.middlewares = append(r.middlewares, fn) } } ``` ## `JWT`身份認證 下載地址: ```golang github.com/dgrijalva/jwt-go" ``` 實現的功能如下: 1. token生成 2. 中間件攔截請求進行token認證 結合代碼: ``` // jwt_svr.go package main import ( "context" "fmt" "github.com/dgrijalva/jwt-go" "github.com/dgrijalva/jwt-go/request" "github.com/gorilla/mux" "net/http" "strings" "time" ) //自定義Claims結構體 type LoginClaims struct { Uid string Name string Pwd string LoginTime time.Duration token string jwt.StandardClaims } //var nowDate = time.Now().Format("2020-02-22 15") var nowDate = "123123123" var secretKey = fmt.Sprintf("%v%v",nowDate,"dingding") //生成token func Sign(uid, name, pwd string) (string, error) { //開始生成token now := time.Now() exp := now.Add(time.Duration(2) * time.Minute) //2分鐘后過期 claims := LoginClaims{ Uid: uid, Name: name, Pwd : pwd, LoginTime : time.Duration(now.Unix()), StandardClaims: jwt.StandardClaims{ ExpiresAt: exp.Unix(), }, } token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims) return token.SignedString([]byte(secretKey)) } //解析token func ParseToken(token string, secret string) (*LoginClaims, error) { loginclaims := new(LoginClaims) claim, err := jwt.ParseWithClaims(token, loginclaims, func(token *jwt.Token) (interface{}, error) { return []byte(secret), nil }) if err != nil { return loginclaims, err } if !claim.Valid { return loginclaims, fmt.Errorf("claim.Valid error") } return loginclaims, nil } func stripBearerPrefixFromTokenString(tok string ) (string, error) { if len(tok) > 4 && strings.ToUpper(tok[0:4]) == "JWT " { return tok[4:], nil } return tok, nil } func main () { r := mux.NewRouter() //生成token t, err := Sign("1", "zjjj", "123") if nil != err { fmt.Errorf(err.Error()) return } //解析token l, err := ParseToken(t, secretKey) if err != nil { fmt.Printf(err.Error()) return } fmt.Printf("generate token: %s\n", t) fmt.Printf("uid: %s\n", l.Uid) //中間件 攔截請求,用來token認證。 r.Use(func(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { mapClaims := new(LoginClaims) //自定義類型 var myToken string // 如果token存在于Authorization中 token, err := request.ParseFromRequest(r, &request.PostExtractionFilter{ Extractor: request.HeaderExtractor{"Authorization"}, Filter: stripBearerPrefixFromTokenString, }, func(token *jwt.Token) (interface{}, error) { return []byte(secretKey), nil }, request.WithClaims(mapClaims)) if !token.Valid { // 如果token存在于header中 for k, v := range r.Header { if strings.ToLower(k) == "token" { myToken = v[0] break } } mapClaims, err = ParseToken(myToken, secretKey) if err != nil { w.Write([]byte("token invalid\n")) return } }else { //myToken = strings.Split(r.Header["Authorization"][0], " ")[1] //第二種獲取Authorization的方式 fmt.Printf("id: %s\n", mapClaims.Uid) } //把解析好的token數據放到context中 longtext := fmt.Sprintf("解析好的tokne數據 id: %s, name: %s, pwd: %s\n", mapClaims.Uid, mapClaims.Name, mapClaims.Pwd) w.Write([]byte(longtext)) ctx := context.WithValue(r.Context(), "id", mapClaims.Uid) ctx = context.WithValue(ctx, "name", mapClaims.Name) r = r.WithContext(ctx) next.ServeHTTP(w, r) }) }) r.HandleFunc("/test", func(w http.ResponseWriter, r *http.Request) { fmt.Printf("handleFunc test\n") w.Write([]byte("test is success")) }) r.HandleFunc("/login", func(w http.ResponseWriter, r *http.Request) { r.ParseForm() //fmt.Fprintln(w,r.Form) name := r.FormValue("name") pwd := r.FormValue("pwd") fmt.Printf("login: name: %s, pwd: %s\n", name, pwd) login, err := Sign("1", name, pwd) if nil != err { fmt.Errorf(err.Error()) w.Write([]byte(err.Error())) return } w.Write([]byte(login)) }) fmt.Printf("Server listen on 8080...\n") http.ListenAndServe(":8080", r) } ``` 驗證一下, 啟動程序: ``` $ go run jwt_svr.go generate token: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJVaWQiOiIxIiwiTmFtZSI6InpqamoiLCJQd2QiOiIxMjMiLCJMb2dpblRpbWUiOjE2MTQxMzg1MzIsImV4cCI6MTYxNDEzODY1Mn0.kHZKlpZXY_qLFaOfr8g1i9uPssjZB3vZFrMqx8S0Ef4 uid: 1 Server listen on 8080... ``` 已經監聽8080端口,使用idea的`rest client`來模擬請求`test`接口,在`Headers`中加入 ``` Authorization:jwt eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJVaWQiOiIxIiwiTmFtZSI6InpqamoiLCJQd2QiOiIxMjMiLCJMb2dpblRpbWUiOjE2MTQxMzg1MzIsImV4cCI6MTYxNDEzODY1Mn0.kHZKlpZXY_qLFaOfr8g1i9uPssjZB3vZFrMqx8S0Ef4 ``` 點擊 `rest client`的運行按鈕,得到數據: ``` 解析好的tokne數據 id: 1, name: zjjj, pwd: 123 test is success ``` 第二種方法是請求`login`接口生成token,參數 `name=''`, `pwd=''`, 生成token后再按照上述方法,請求`test`接口
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看