将服务开放:API接口与用户认证实践指南 | 青训营

63 阅读3分钟

API接口设计规范参考

在现代软件开发中,将服务开放给用户是实现功能共享和扩展性的关键一步。了解掌握API接口设计是完成服务开放的重要步骤。API接口设计规范参考:

路由命名规范

动作前缀备注
获取getget{XXX}
获取getget{XXX}List
新增addadd{XXX}
修改updateupdate{XXX}
保存savesave{XXX}
删除deletedelete{XXX}
上传uploadupload{XXX}
发送sendsend{XXX}

请求方式

请求方式描述
GET获取数据
POST新增数据
PUT更新数据
DELETE删除数据

请求参数

Query

url?后面的参数,存放请求接口的参数数据。

Header

请求头,存放公共参数、requestId、token、加密字段等。

Body

Body体,存放请求接口的参数数据。

定义用户数据结构

定义一个结构体来表示用户数据。结构体包含用户名和密码两个字段。用户名和密码是用户登录时需要提供的信息,用于验证用户身份。

type User struct {
    Username string `json:"Username"`
    Password string `json:"Password"`
}

处理用户登录请求

定义一个函数来处理用户登录请求。函数接收两个参数: http.ResponseWriter*http.Request ,并返回一个 JSON 格式的响应。

首先,解析请求中的 JSON 数据,并将其存储到一个 User 类型的变量中。然后,验证用户名和密码是否正确。如果验证通过,则返回登录成功的信息;否则返回错误信息。

func handlerLogin(w http.ResponseWriter, r *http.Request) {
    // 解析请求中的 JSON 数据,用户名和密码
    var user User
    err := json.NewDecoder(r.Body).Decode(&user)
    if err != nil {
        http.Error(w, err.Error(), http.StatusBadRequest)
        return
    }
    // 验证用户名和密码是否正确
    if user.Username == "user1" && user.Password == "123456" {
        // 登录成功,返回成功信息
        w.Header().Set("Content-Type", "application/json")
        json.NewEncoder(w).Encode(map[string]string{
            "message": "登录成功",
        })
    } else {
        // 登录失败,返回错误信息
        http.Error(w, "用户名或密码错误", http.StatusUnauthorized)
    }
}

启动 HTTP 服务器

最后,在主函数中启动 HTTP 服务器,并注册定义的登录处理函数。HTTP 服务器负责监听客户端请求,并将其分发给相应的处理函数。

func main() {
    http.HandlerFunc("/login", handlerLogin)

    err := http.ListenAndServe(":8080", nil)
    if err != nil {
        panic(err)
    }
}

用户认证

JWT是一种用户双方之间传递安全信息的简洁的、URL安全的表述性声明规范。JWT(Json Web Token)作为一个开放的标准(RFC 7519),定义了一种简洁的、自包含的方法用于通信双方之间以Json对象的形式进行安全性信息传递,传递时有数字签名所以信息时安全的,JWT使用RSA公钥密钥的形式进行签名。

安装JWT包:

go get github.com/dgrijalva/jwt-go

token的组成:

token一共由三部分组成:

  1. 协议头(header):token使用的加密协议
  2. 荷载:储存的是token发放时间、发放人、主题等信息
  3. 第三部分:前面两部分+key进行hash的一个值

获取Token

common包下的jwt.go:

package common
 
import (
    "ginTest/model"
    "github.com/dgrijalva/jwt-go"
    "time"
)
 
// 定义一个jwt加密的密钥
var jwtKey = []byte("a_secret_crect")
 
// 定义token的Claims
type Claims struct {
    UserId uint
    jwt.StandardClaims
}
 
// 登录成功之后就调用这个方法来释放token
func ReleaseToken(user model.User) (string, error) {
    //定义token的过期时间:7天
    expirationTime := time.Now().Add(7 * 24 * time.Hour)
    claims := &Claims{
        UserId: user.ID,
        StandardClaims: jwt.StandardClaims{
            ExpiresAt: expirationTime.Unix(),
            IssuedAt:  time.Now().Unix(), //token发放的时间
            Issuer:    "linxi",           //发放人
            Subject:   "user token",      //主题
        },
    }
    token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
    //使用jwt密钥来生成token
    tokenString, err := token.SignedString(jwtKey)
    if err != nil {
        return "", err
    }
    return tokenString, nil
}

controller包的User.go:

package controller

func login(c *gin.Context){
    //发放token   
    token, err := common.ReleaseToken(user)
    if err != nil {
        ctx.JSON(http.StatusInternalServerError, gin.H{"code": 500, "msg": "系统异常"})
        log.Printf("token generate error :%v ", err)
        return
    }
}

Token 用户认证

1、客户端发送请求到API服务时包含认证信息(一般是用户名或邮箱以及密码)。

2、API服务验证认证信息是否正确,并生成代表用户身份的bearer token(不记名令牌)返回给客户端。token在一段时间后过期,在此之后,用户将需要重新提交他们的凭证以获得一个新的token。

3、对于后续的API请求,客户端将拿到的token放在Authorization请求头中。