[英]Go and JWT - Simple authentication
I'm currently making an API (with go) and I'm working on the session part.我目前正在制作一个 API(使用 go)并且我正在处理会话部分。 After research about what to use for session, I found JWT really interesting.
在研究了会话使用什么之后,我发现 JWT 真的很有趣。
However I'm not really sure to understand how to use it after some tutorials.但是,在学习了一些教程后,我不确定如何使用它。 So this is my idea:
所以这是我的想法:
func main() {
router := mux.NewRouter().StrictSlash(true)
router.HandleFunc("/login", login)
router.HandleFunc("/logout", logout)
router.HandleFunc("/register", register)
http.ListenAndServe(":8080", router)
}
After those requests handled, I create the differents functions.处理完这些请求后,我创建了不同的函数。
func login(w http.ResponseWriter, r *http.Request) {
/*
Here I just have to search in my database (SQL, I know how to do it). If the user is registered, I create a token and give it to him, but how can I do it?
*/
}
func logout(w http.ResponseWriter, r *http.Request) {
/*
I get a token and stop/delete it?
*/
}
func register(w http.ResponseWriter, r *http.Request) {
/*
I search if the user isn't register and then, if it isn't, I create a user in the database (I know how to do it). I connect him but again, how to make a new token?
*/
}
Lot of tutorials on the web seems really hard but I just want something simple.网络上的很多教程看起来真的很难,但我只想要一些简单的东西。 I just want an handle package (code above) which work with a service package to have something like an engine token authentication.
我只想要一个句柄包(上面的代码),它与服务包一起使用,具有引擎令牌身份验证之类的功能。
A second point I'm not sure to understand is the saving of the token.我不确定的第二点是代币的保存。 If a user connects himself, then what would be best?
如果用户连接自己,那么什么是最好的? Each time the user runs their app, the app connects itself and get a new token from saved information (user/password) or the app just save the token forever?
每次用户运行他们的应用程序时,应用程序都会连接自己并从保存的信息(用户/密码)中获取新令牌,还是应用程序永远保存令牌? And what about the server, is the token managed and saved automatically with JWT or do I have to put it in my sql database?
那么服务器呢,令牌是用 JWT 自动管理和保存的,还是我必须把它放在我的 sql 数据库中?
Thank for your help !感谢您的帮助!
EDIT 1编辑 1
Thank you !谢谢! So after I read your answer, I encapsulated my code (token.go) like it
所以在我阅读了你的答案后,我像这样封装了我的代码(token.go)
package services
import (
"fmt"
"github.com/dgrijalva/jwt-go"
"time"
"../models"
)
var tokenEncodeString string = "something"
func createToken(user models.User) (string, error) {
// create the token
token := jwt.New(jwt.SigningMethodHS256)
// set some claims
token.Claims["username"] = user.Username;
token.Claims["password"] = user.Password;
token.Claims["exp"] = time.Now().Add(time.Hour * 72).Unix()
//Sign and get the complete encoded token as string
return (token.SignedString(tokenEncodeString))
}
func parseToken(unparsedToken string) (bool, string) {
token, err := jwt.Parse(unparsedToken, func(token *jwt.Token) (interface{}, error) {
// Don't forget to validate the alg is what you expect:
if _, ok := token.Method.(*jwt.SigningMethodRSA); !ok {
return nil, fmt.Errorf("Unexpected signing method: %v", token.Header["alg"])
}
return myLookupKey(token.Header["kid"]), nil
})
if err == nil && token.Valid {
return true, unparsedToken
} else {
return false, ""
}
}
However, I got the following error: "token.go: undefined: myLookupKey" I looked on internet and I found an encapsulated function which have this prototype:但是,我收到以下错误:“token.go:undefined:myLookupKey”我在互联网上查看并找到了一个具有此原型的封装函数:
func ExampleParse(myToken string, myLookupKey func(interface{}) (interface{}, error)) {
/* same code in my func parseToken() */
}
So what are the difference between my function and this one?那么我的函数和这个函数有什么区别呢? How can I use this one?
我怎样才能使用这个?
Thanks !谢谢!
To start, you need to import a JWT library in Golang (go get github.com/dgrijalva/jwt-go).首先,您需要在 Golang 中导入一个 JWT 库(去 github.com/dgrijalva/jwt-go)。 You can find that library documentation in below link.
您可以在以下链接中找到该库文档。
https://github.com/dgrijalva/jwt-go https://github.com/dgrijalva/jwt-go
Firstly, you need to create a token首先,您需要创建一个令牌
// Create the token
token := jwt.New(jwt.SigningMethodHS256)
// Set some claims
token.Claims["foo"] = "bar"
token.Claims["exp"] = time.Now().Add(time.Hour * 72).Unix()
// Sign and get the complete encoded token as a string
tokenString, err := token.SignedString(mySigningKey)
Secondly, parse that token其次,解析该令牌
token, err := jwt.Parse(myToken, func(token *jwt.Token) (interface{}, error) {
// Don't forget to validate the alg is what you expect:
if _, ok := token.Method.(*jwt.SigningMethodRSA); !ok {
return nil, fmt.Errorf("Unexpected signing method: %v", token.Header["alg"])
}
return myLookupKey(token.Header["kid"]), nil
})
if err == nil && token.Valid {
deliverGoodness("!")
} else {
deliverUtterRejection(":(")
}
Also, there are some examples for use JWT in GOlang like this https://github.com/slok/go-jwt-example此外,还有一些在 GOlang 中使用 JWT 的示例,例如https://github.com/slok/go-jwt-example
EDIT-1编辑-1
package main
import (
"fmt"
"time"
"github.com/dgrijalva/jwt-go"
)
const (
mySigningKey = "WOW,MuchShibe,ToDogge"
)
func main() {
createdToken, err := ExampleNew([]byte(mySigningKey))
if err != nil {
fmt.Println("Creating token failed")
}
ExampleParse(createdToken, mySigningKey)
}
func ExampleNew(mySigningKey []byte) (string, error) {
// Create the token
token := jwt.New(jwt.SigningMethodHS256)
// Set some claims
token.Claims["foo"] = "bar"
token.Claims["exp"] = time.Now().Add(time.Hour * 72).Unix()
// Sign and get the complete encoded token as a string
tokenString, err := token.SignedString(mySigningKey)
return tokenString, err
}
func ExampleParse(myToken string, myKey string) {
token, err := jwt.Parse(myToken, func(token *jwt.Token) (interface{}, error) {
return []byte(myKey), nil
})
if err == nil && token.Valid {
fmt.Println("Your token is valid. I like your style.")
} else {
fmt.Println("This token is terrible! I cannot accept this.")
}
}
Just to make update of @massoud-afrashteh answer.只是为了更新@massoud-afrashteh 的答案。 In version 3 of jwt-go setting clams should be
在 jwt-go 设置的第 3 版中,蛤蜊应该是
// Set some claims
claims := make(jwt.MapClaims)
claims["foo"] = "bar"
claims["exp"] = time.Now().Add(time.Hour * 72).Unix()
token.Claims = claims
Don't forget to run the command go get github.com/dgrijalva/jwt-go
.不要忘记运行命令
go get github.com/dgrijalva/jwt-go
。
Another way to create more simple:另一种创建更简单的方法:
token := jwt.NewWithClaims(jwt.SigningMethodHS256, jwt.MapClaims{
"foo": "bar",
"nbf": time.Date(2015, 10, 10, 12, 0, 0, 0, time.UTC).Unix(),
})
tokenString, err := token.SignedString([]byte("your key"))
fmt.Println(tokenString, err)
func GenerateToken(mySigningKey []byte, username string) (string, error) {
// Create the token
token := jwt.New(jwt.SigningMethodRS512)
claims := make(jwt.MapClaims)
claims[collections.PARAM_USER_NAME] = username
claims["exp"] = time.Now().Add(time.Hour * 72).Unix()
token.Claims = claims
return token.SignedString(mySigningKey)
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.