《Web Development with Go》JWT认证满意版
2021-05-12 21:30
标签:init wro util muse response pre ssi starting pack 这个比昨晚的要满意, 认证放到中间件那里了。 Mux使用的是gorilla, 中间件使用的是negroni, 启动是用的negroni.classic方法。 《Web Development with Go》JWT认证满意版 标签:init wro util muse response pre ssi starting pack 原文地址:https://www.cnblogs.com/aguncn/p/12004610.htmlpackage main
import (
"encoding/json"
"fmt"
"io/ioutil"
"log"
"net/http"
"time"
"github.com/codegangsta/negroni"
jwt "github.com/dgrijalva/jwt-go"
"github.com/dgrijalva/jwt-go/request"
"github.com/gorilla/mux"
)
// using asymmetric crypto/RSA keys
// location of the files used for signing and verification
const (
privKeyPath = "keys/app.rsa" // openssl genrsa -out app.rsa 1024
pubKeyPath = "keys/app.rsa.pub" // openssl rsa -in app.rsa -pubout > app.rsa.pub
)
const (
SecretKey = "welcome to wangshubo‘s blog"
)
// verify key and sign key
var (
verifyKey, signKey []byte
)
//struct User for parsing login credentials
type User struct {
UserName string `json:"username"`
Password string `json:"password"`
}
// read the key files before starting http handlers
func init() {
var err error
signKey, err = ioutil.ReadFile(privKeyPath)
if err != nil {
log.Fatal("Error reading private key")
return
}
verifyKey, err = ioutil.ReadFile(pubKeyPath)
if err != nil {
log.Fatal("Error reading private key")
return
}
}
func authMiddleware(w http.ResponseWriter, r *http.Request, next http.HandlerFunc) {
// validate the token
pubKey, err := jwt.ParseRSAPublicKeyFromPEM(verifyKey)
if err != nil {
fmt.Println("ParseRSAPublicKeyFromPEM:", err.Error())
return
}
token, err := request.ParseFromRequest(r,
request.AuthorizationHeaderExtractor,
func(token *jwt.Token) (interface{}, error) {
// since we only use one private key to sign the tokens,
// we also only use its public counter part to verify
return pubKey, nil
})
if err == nil && token.Valid {
next(w, r)
} else {
w.WriteHeader(http.StatusUnauthorized)
fmt.Fprint(w, "Authentication failed")
}
}
// reads the login credentials, checks them and creates JWT the token
func loginHandler(w http.ResponseWriter, r *http.Request) {
var user User
//decode into User struct
err := json.NewDecoder(r.Body).Decode(&user)
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
fmt.Fprintln(w, "Error in request body")
return
}
log.Println(user.UserName, user.Password)
// validate user credentials
if user.UserName != "shijuvar" || user.Password != "pass" {
w.WriteHeader(http.StatusForbidden)
fmt.Fprintln(w, "Wrong info")
return
}
// create a signer for rsa 256
t := jwt.New(jwt.SigningMethodRS256)
// set our claims
claims := make(jwt.MapClaims)
claims["iss"] = "admin"
claims["CustomUserInfo"] = struct {
Name string
Role string
}{user.UserName, "Member"}
claims["exp"] = time.Now().Add(time.Minute * 20).Unix()
t.Claims = claims
priKey, err := jwt.ParseRSAPrivateKeyFromPEM(signKey)
if err != nil {
fmt.Println("ParseRSAPrivateKeyFromPEM:", err.Error())
return
}
tokenString, err := t.SignedString(priKey)
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
fmt.Fprintln(w, "Sorry, error while Signing Token!")
log.Printf("Token Signing error: %v\n", err)
return
}
response := Token{tokenString}
jsonResponse(response, w)
}
// only accessible with a valid token
func authHandler(w http.ResponseWriter, r *http.Request) {
response := Response{"Authorized to the system"}
jsonResponse(response, w)
}
type Response struct {
Text string `json:"text"`
}
type Token struct {
Token string `json:"token"`
}
func jsonResponse(response interface{}, w http.ResponseWriter) {
json, err := json.Marshal(response)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
w.WriteHeader(http.StatusOK)
w.Header().Set("Content-Type", "application/json")
w.Write(json)
}
//Entry point of the program
func main() {
r := mux.NewRouter()
r.HandleFunc("/login", loginHandler).Methods("POST")
r.Handle("/auth", negroni.New(
negroni.HandlerFunc(authMiddleware),
negroni.Wrap(http.HandlerFunc(authHandler)),
)).Methods("POST")
n := negroni.Classic()
n.UseHandler(r)
n.Run(":8080")
}
文章标题:《Web Development with Go》JWT认证满意版
文章链接:http://soscw.com/index.php/essay/84864.html