goal 的使用者認證(Auth)模組完成,離生產環境又雙叒叕近了一步!

qbhy發表於2022-02-03

goal-web/auth
goal 框架的使用者認證元件,你可以在 httpwebsocket 或者其他環境使用,有上下文即可。

安裝 - install

go get github.com/goal-web/auth

使用 - usage

goal 的腳手架自帶了絕大多數開發一個 web 應用的所需要的功能和元件,當然這也包括了認證元件。一般情況下,我們只需要在 .env 修改自己的認證配置即可,比如 jwt 驅動的 secret、session 驅動的 session_key。

配置 - config

預設情況下,config/auth.go 配置檔案像下面那樣,預設新增了 jwtsession 兩個守衛配置

package config

import (
    "github.com/goal-web/auth"
    "github.com/goal-web/contracts"
    "github.com/goal-web/example/models"
    "github.com/golang-jwt/jwt"
)

func init() {
    configs["auth"] = func(env contracts.Env) interface{} {
        return auth.Config{
            Defaults: struct {
                Guard string
                User  string
            }{
                Guard: env.StringOption("auth.default", "jwt"), // 預設守衛
                User:  env.StringOption("auth.user", "db"), // 預設使用者提供者
            },
            Guards: map[string]contracts.Fields{
                "jwt": { // 守衛名稱
                    "driver":   "jwt", // 驅動,目前支援jwt、session
                    "secret":   env.GetString("auth.jwt.secret"), // jwt 簽名所需的 secret,不同的守衛建議不同的secret
                    "method":   jwt.SigningMethodHS256, // jwt 簽名方法
                    "lifetime": 60 * 60 * 24, // token有效時長,單位:秒
                    "provider": "db", // 使用者提供者名
                },
                "session": { // 守衛名稱
                    "driver":      "session", // 驅動名
                    "provider":    "db", // 使用者提供者名
                    // session驅動所需的引數,如果應用需要配置多個session驅動的守衛,那麼需要配置不一樣的 session_key
                    "session_key": env.StringOption("auth.session.key", "auth_session"), 
                },
            },
            Users: map[string]contracts.Fields{ // 使用者提供者,目前只支援 db
                "db": { // 使用者提供者名稱
                    "driver": "db", // 驅動名稱
                    "model":  models.UserModel, // 使用者模型
                },
            },
        }
    }
}

.env 的資料庫相關配置

# 預設連線
auth.jwt.secret=jwt_secret
auth.default=jwt

定義模型 - define a model

app/models/user.go 檔案

package models

import (
    "github.com/goal-web/database/table"
    "github.com/goal-web/supports/class"
)

var (
    UserModel = table.NewModel(class.Make(new(User)), "users")
)

func UserQuery() *table.Table {
    return table.FromModel(UserModel)
}

type User struct {
    Id       string `json:"id"`
    NickName string `json:"name"`
}

// GetId 實現了 contracts.Authenticatable 介面,此方法必不可少
func (u User) GetId() string {
    return u.Id
}

用法 - method of use

package controllers

import (
    "github.com/goal-web/contracts"
    "github.com/goal-web/example/models"
)

func LoginExample(guard contracts.Guard) contracts.Fields {
    //  這是虛擬碼
    user := models.UserQuery().First().(models.User)

    return contracts.Fields{
        "token": guard.Login(user), // jwt 返回 token,session 返回 true
    }
}

func GetCurrentUser(guard contracts.Guard) interface{} {
    return contracts.Fields{
        "user": guard.User(), // 已登入返回使用者模型,否則返回 nil
    }
}

使用中介軟體

package routes

import (
    "github.com/goal-web/auth"
    "github.com/goal-web/contracts"
    "github.com/goal-web/example/app/http/controllers"
    "github.com/goal-web/session"
)

func ApiRoutes(router contracts.Router) {

    v1 := router.Group("", session.StartSession)

    // 直接應用在路由上
    v1.Get("/myself", controllers.GetCurrentUser, auth.Guard("jwt"))

    // 應用在路由組上
    authRouter := v1.Group("", auth.Guard("jwt"))
    authRouter.Get("/myself", controllers.GetCurrentUser, auth.Guard("jwt"))

}

守衛API - guard api

type Guard interface {
    Once(user Authenticatable)
    User() Authenticatable
    GetId() string
    Check() bool
    Guest() bool
    Login(user Authenticatable) interface{}
}

擴充套件守衛和使用者提供者 - extension

這部分內容比較多,這裡暫時不展開講,後面會專門錄影片介紹,歡迎大家點贊訂閱

在 goal 之外的框架使用 - use in frameworks other than goal

這部分內容比較多,這裡暫時不展開講,後面會專門錄影片介紹,歡迎大家點贊訂閱

goal-web
goal-web/auth
qbhy0715@qq.com

本作品採用《CC 協議》,轉載必須註明作者和本文連結

相關文章