Introduction
上一篇已经完成了 JWT 的部分功能
接着开始完善 JWT 功能
Sample Code
完成后的资料夹结构如下
CreateUser
schema.resolvers.go
实现 CreateUser funciotn
func (r *mutationResolver) CreateUser(ctx context.Context, input model.NewUser) (string, error) {var user users.Useruser.Username = input.Usernameuser.Password = input.Passworduser.Create()token, err := jwt.GenerateToken(user.Username)if err != nil{return "", err}return token, nil}
$ go run server.go
测试一下 CreateUser 能不能成功
打开 http://localhost:8080/
输入
mutation { createUser(input: {username: "user1", password: "123"})}
接着会得到一串 JWT string
{ "data": { "createUser": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE2ODM2MjU1ODcsInVzZXJuYW1lIjoidXNlcjEifQ.FUO8LH8G_FioVmVVMqVhQiqEndmbK_QIdq5KlHFWtwY" }}
Login
这阶段开始实作当输入了正确的帐号密码,就会产生 JWT Token 给 userinternal/users/users.go
实作 Authenticate function
不过要注意一下...这段 Query 是练习做实验才用的,不然这样是有暴露密码的危险性
func (user *User) Authenticate() bool {statement, err := mig.Db.Prepare("select Password from Users WHERE Username = ?")if err != nil {log.Fatal(err)}row := statement.QueryRow(user.Username)var hashedPassword stringerr = row.Scan(&hashedPassword)if err != nil {if err == sql.ErrNoRows {return false} else {log.Fatal(err)}}return CheckPasswordHash(user.Password, hashedPassword)}
schema.resolvers.go
实作 Login function
func (r *mutationResolver) Login(ctx context.Context, input model.Login) (string, error) {var user users.Useruser.Username = input.Usernameuser.Password = input.Passwordcorrect := user.Authenticate()if !correct {// 1return "", &users.WrongUsernameOrPasswordError{}}token, err := jwt.GenerateToken(user.Username)if err != nil{return "", err}return token, nil}
internal/users/errors.go
处理错误回传
package userstype WrongUsernameOrPasswordError struct{}func (m *WrongUsernameOrPasswordError) Error() string {return "wrong username or password"}
schema.resolvers.go
处理 Refresh Token
func (r *mutationResolver) RefreshToken(ctx context.Context, input model.RefreshTokenInput) (string, error) {username, err := jwt.ParseToken(input.Token)if err != nil {return "", fmt.Errorf("access denied")}token, err := jwt.GenerateToken(username)if err != nil {return "", err}return token, nil}