package main
import (
“fmt”
jwt “github.com/dgrijalva/jwt-go”
“github.com/julienschmidt/httprouter”
“log”
“net/http”
“time”
)
func BasicAuth(h httprouter.Handle, requiredUser, requiredPassword string) httprouter.Handle {
return func(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
user, password, hasAuth := r.BasicAuth()
if hasAuth && user == requiredUser && password == requiredPassword {
h(w, r, ps)
} else {
w.Header().Set(“WWW-Authenticate”, “Basic realm=Restricted”)
http.Error(w, http.StatusText(http.StatusUnauthorized), http.StatusUnauthorized)
}
}
}
//jwt权限
var jwtKey = []byte(“123456”)
var users = map[string]string{
“admin”: “123456”,
“abc”: “123”,
}
type Credentials struct {
Password string json:"password"
Username string json:"username"
}
type Claims struct {
Username string json:"username"
jwt.StandardClaims
}
func Signin(w http.ResponseWriter, r *http.Request,_ httprouter.Params) {
var creds Credentials
expirationTime := time.Now().Add(1 * time.Minute)//1分钟过期
claims := &Claims{
Username: creds.Username,
StandardClaims: jwt.StandardClaims{
ExpiresAt: expirationTime.Unix(),
},
}
token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
tokenString, err := token.SignedString(jwtKey)
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
return
}
http.SetCookie(w, &http.Cookie{
Name: “token”,
Value: tokenString,
Expires: expirationTime,
})
}
func Refresh(w http.ResponseWriter, r *http.Request,_ httprouter.Params) {
c, err := r.Cookie(“token”)
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
w.Write([]byte(“token不存在”))
return
}
tknStr := c.Value
claims := &Claims{}
fmt.Println(“新的token:”,tknStr)
jwt.ParseWithClaims(tknStr, claims, func(token *jwt.Token) (interface{}, error) {
return jwtKey, nil
})
expirationTime := time.Now().Add(5 * time.Minute)
claims.ExpiresAt = expirationTime.Unix()
token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
tokenString, err := token.SignedString(jwtKey)
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
w.Write([]byte(“token不存在”))
return
}
http.SetCookie(w, &http.Cookie{
Name: “token”,
Value: tokenString,
Expires: expirationTime,
})
}
func Index(w http.ResponseWriter, r http.Request, _ httprouter.Params) {
fmt.Fprint(w, “权限验证成功!\n”)
}
func Hello(w http.ResponseWriter,r *http.Request, rx httprouter.Params) {
c,err:= r.Cookie(“token”)
if err != nil {
if err == http.ErrNoCookie {
w.WriteHeader(http.StatusUnauthorized)
w.Write([]byte(“禁止访问”))
return
}
w.WriteHeader(http.StatusBadRequest)
return
}
tknStr := c.Value
claims := &Claims{}
tkn, _ := jwt.ParseWithClaims(tknStr, claims, func(token *jwt.Token) (interface{}, error) {
return jwtKey, nil
})
if !tkn.Valid {
w.WriteHeader(http.StatusUnauthorized)
w.Write([]byte(“禁止访问”))
return
}
w.Write([]byte(fmt.Sprintf(“Welcome %s!”, claims.Username)))
fmt.Fprintf(w, “hello, %s!\n”, rx.ByName(“name”))
}
func main() {
r := httprouter.New()
r.GlobalOPTIONS = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {//cors
if r.Header.Get(“Access-Control-Request-Method”) != “” {
header := w.Header()
header.Set(“Access-Control-Allow-Methods”, header.Get(“Allow”))
header.Set(“Access-Control-Allow-Origin”, ““)
}
w.WriteHeader(http.StatusNoContent)
})
r.GET(“/“, BasicAuth(Index, “admin”, “123456”))
r.GET(“/hello/:name”, Hello)
r.GET(“/signin”, Signin)
r.GET(“/refresh”, Refresh)
r.ServeFiles(“/public/*filepath”, http.Dir(“public”))//静态文件服务器
r.NotFound=http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, “没有找到这个文件”)
})
log.Fatal(http.ListenAndServe(“:8000”, r))
}