如何将我的服务开放给用户:构建 API 接口和用户认证的实践指南 | 青训营

84 阅读5分钟

首先,我们需要了解

什么是API接口?

简单来说,API是一种规定了如何访问特定软件组件或数据的方法、协议和工具集合。 在软件开发中,API接口通常被用来实现不同系统、应用程序之间的协作。通过API接口,系统或应用程序可以相互访问和交换数据。例如,社交媒体平台的API接口可以让其他应用程序获取和发布用户数据,比如微信公众号可以利用这种接口和用户进行互动。 API接口通常提供了一套方法、函数、类或对象,开发者可以根据它们的参数来调用API接口。这些参数可以获取或修改特定数据,运行特定的任务或获得特定的结果。 API接口的另一个重要特性是它们通常是跨平台的。这意味着开发者可以在任何操作系统或编程语言中使用API接口,只要它们符合API的规范。 总之,API接口让不同系统或应用程序之间的数据传输变得更加简便快捷,并且方便开发者根据自己的需求调用数据和服务。在软件开发中,API接口已经成为了一个不可或缺的组成部分。 而对于web的后端服务来说API是你的服务与外界交流的窗口。它就像是你服务的门卫,决定了谁可以进来,以及他们可以做什么。通过API接口,用户可以请求数据、提交信息、执行操作等。

如何构建API接口

我们采用的是go语言进行编写,在GO语言中,我们可以使用net/http包来构建一个服务

package main

import (
    "fmt"
    "net/http"
)

func helloHandler(w http.ResponseWriter, r *http.Request) {
    fmt.Fprintf(w, "pong")
}

func main() {
    http.HandleFunc("/ping", helloHandler)
    http.ListenAndServe(":8080", nil)
}

那么当用户请求/ping路径时,会返回"pong"

API文档

提供清晰明了的API文档,是对用户友好的重要一环。文档应该包含所有可用的API端点、参数、请求和响应示例,以及可能的错误码和错误信息。Swagger等API文档工具可以帮助你自动生成API文档。

对用户鉴权,保证api的安全

在GO语言中,可以使用gorilla/mux包来实现路由和jwt-go包来处理JWT令牌。让我们来看一个示例

package main

import (
    "fmt"
    "net/http"
    "github.com/gorilla/mux"
    "github.com/dgrijalva/jwt-go"
)

func authMiddleware(next http.HandlerFunc) http.HandlerFunc {
    return func(w http.ResponseWriter, r *http.Request) {
        tokenString := r.Header.Get("Authorization")
        if tokenString == "" {
            http.Error(w, "未提供令牌", http.StatusUnauthorized)
            return
        }

        token, err := jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) {
            return []byte("your-secret-key"), nil
        })

        if err != nil || !token.Valid {
            http.Error(w, "令牌无效", http.StatusUnauthorized)
            return
        }

        next(w, r)
    }
}

func helloHandler(w http.ResponseWriter, r *http.Request) {
    fmt.Fprintf(w, "pong")
}

func main() {
    r := mux.NewRouter()

    r.HandleFunc("/ping", authMiddleware(helloHandler))
    http.Handle("/", r)

    http.ListenAndServe(":8080", nil)
}

上面的代码实现了一个简单的JWT令牌认证中间件,用户在请求头中提供JWT令牌进行认证。

标准化

REST API

REST(Representational State Transfer,表述性状态转移)是一种用于构建分布式系统的架构风格。REST API(Application Programming Interface,应用程序接口)是一种基于REST风格的网络API,通常用于Web服务中。REST API使用常见的HTTP方法(如GET、POST、PUT、DELETE等)与Web服务交互,通过URI(Uniform Resource Identifier,统一资源标识符)定位资源。

REST API的设计原则 REST API遵循以下6个设计原则:

无状态(Stateless):每个请求都必须包含所有的信息,服务器不应该存储客户端的上下文信息。这意味着每个API请求都是独立的,请求之间没有相互依赖关系。

客户端 - 服务器(Client-Server):REST API遵循客户端-服务器模型,客户端负责用户界面,服务器负责处理业务逻辑和数据存储。这种分离使得客户端和服务器可以独立地进行开发和演进。

缓存(Cacheable):客户端可以缓存服务器的响应。服务器必须在响应中明确指示响应是否可以被缓存,以及缓存的有效期。这有助于提高性能和减少服务器负载。

分层系统(Layered System):REST API可以分为多层,每层负责特定功能。客户端只需要与最外层进行交互,而无需了解底层实现细节。这有助于提高系统的可扩展性和可维护性。

统一接口(Uniform Interface):REST API具有统一的接口约定,使得API易于理解和使用。这包括使用HTTP方法(GET、POST、PUT、DELETE等)、资源定位(URI)和媒体类型(如JSON、XML等)。

代码在需(Code-on-Demand,可选):服务器可以向客户端发送可执行代码(如JavaScript),以便在客户端上执行。这可以减少客户端的复杂性,但可能会影响应用程序的可移植性。

下面是使用gin框架来创建一个简单的RESTful API的例子:

package main

import (
 "encoding/json"
 "fmt"
 "log"
 "net/http"
)

type User struct {
 ID       int    `json:"id"`
 Name     string `json:"name"`
 Age      int    `json:"age"`
}

var users []User

func main() {
 http.HandleFunc("/users", getUsers)
 http.HandleFunc("/users/", newUser)
 log.Fatal(http.ListenAndServe(":8080", nil))
}

func getUsers(w http.ResponseWriter, r *http.Request) {
 w.Header().Set("Content-Type", "application/json")
 json.NewEncoder(w).Encode(users)
}

func newUser(w http.ResponseWriter, r *http.Request) {
 w.Header().Set("Content-Type", "application/json")
 var user User
 _ = json.NewDecoder(r.Body).Decode(&user)
 users = append(users, user)
 json.NewEncoder(w).Encode(user)
}



    

在这个示例中,我们定义了一个User结构体和一个users切片来存储用户数据。我们还定义了两个处理函数:getUsers用于获取所有用户,newUser用于创建新用户。