golang进行简单权限认证的实现

 更新时间:2021年09月23日 11:37:24   作者:wilson_go  
本文主要介绍了golang简单权限认证的实现,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

使用JWT进行认证

JSON Web Tokens (JWT) are a more modern approach to authentication.

As the web moves to a greater separation between the client and server, JWT provides a wonderful alternative to traditional cookie based authentication models.

JWTs provide a way for clients to authenticate every request without having to maintain a session or repeatedly pass login credentials to the server.

用户注册之后, 服务器生成一个 JWT token返回给浏览器, 浏览器向服务器请求数据时将 JWT token 发给服务器, 服务器用 signature 中定义的方式解码

JWT 获取用户信息.

一个 JWT token包含3部分:
1 header: 告诉我们使用的算法和 token 类型
2 Payload: 必须使用 sub key 来指定用户 ID, 还可以包括其他信息比如 email, username 等.
3 Signature: 用来保证 JWT 的真实性. 可以使用不同算法

package main

import (
	"encoding/json"
	"fmt"
	"log"
	"net/http"
	"strings"
	"time"

	"github.com/codegangsta/negroni"
	"github.com/dgrijalva/jwt-go"
	"github.com/dgrijalva/jwt-go/request"
)
const (
	SecretKey = "welcome ---------"
)

func fatal(err error) {
	if err != nil {
		log.Fatal(err)
	}
}

type UserCredentials struct {
	Username string `json:"username"`
	Password string `json:"password"`
}

type User struct {
	ID       int    `json:"id"`
	Name     string `json:"name"`
	Username string `json:"username"`
	Password string `json:"password"`
}

type Response struct {
	Data string `json:"data"`
}

type Token struct {
	Token string `json:"token"`
}

func StartServer() {

	http.HandleFunc("/login", LoginHandler)

	http.Handle("/resource", negroni.New(
		negroni.HandlerFunc(ValidateTokenMiddleware),
		negroni.Wrap(http.HandlerFunc(ProtectedHandler)),
	))

	log.Println("Now listening...")
	http.ListenAndServe(":8087", nil)
}

func main() {
	StartServer()
}

func ProtectedHandler(w http.ResponseWriter, r *http.Request) {

	response := Response{"Gained access to protected resource"}
	JsonResponse(response, w)

}

func LoginHandler(w http.ResponseWriter, r *http.Request) {

	var user UserCredentials

	err := json.NewDecoder(r.Body).Decode(&user)

	if err != nil {
		w.WriteHeader(http.StatusForbidden)
		fmt.Fprint(w, "Error in request")
		return
	}

	if strings.ToLower(user.Username) != "someone" {
		if user.Password != "p@ssword" {
			w.WriteHeader(http.StatusForbidden)
			fmt.Println("Error logging in")
			fmt.Fprint(w, "Invalid credentials")
			return
		}
	}

	token := jwt.New(jwt.SigningMethodHS256)
	claims := make(jwt.MapClaims)
	claims["exp"] = time.Now().Add(time.Hour * time.Duration(1)).Unix()
	claims["iat"] = time.Now().Unix()
	token.Claims = claims

	if err != nil {
		w.WriteHeader(http.StatusInternalServerError)
		fmt.Fprintln(w, "Error extracting the key")
		fatal(err)
	}

	tokenString, err := token.SignedString([]byte(SecretKey))
	if err != nil {
		w.WriteHeader(http.StatusInternalServerError)
		fmt.Fprintln(w, "Error while signing the token")
		fatal(err)
	}

	response := Token{tokenString}
	JsonResponse(response, w)

}

func ValidateTokenMiddleware(w http.ResponseWriter, r *http.Request, next http.HandlerFunc) {

	token, err := request.ParseFromRequest(r, request.AuthorizationHeaderExtractor,
		func(token *jwt.Token) (interface{}, error) {
			return []byte(SecretKey), nil
		})

	if err == nil {
		if token.Valid {
			next(w, r)
		} else {
			w.WriteHeader(http.StatusUnauthorized)
			fmt.Fprint(w, "Token is not valid")
		}
	} else {
		w.WriteHeader(http.StatusUnauthorized)
		fmt.Fprint(w, "Unauthorized access to this resource")
	}

}

func JsonResponse(response interface{}, w http.ResponseWriter) {

	json, err := json.Marshal(response)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}

	w.WriteHeader(http.StatusOK)
	w.Header().Set("Content-Type", "application/json")
	w.Write(json)
}

在这里插入图片描述

在这里插入图片描述

到此这篇关于golang进行简单权限认证的实现的文章就介绍到这了,更多相关golang 权限认证内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Golang中crypto/ecdsa库实现数字签名和验证

    Golang中crypto/ecdsa库实现数字签名和验证

    本文主要介绍了Golang中crypto/ecdsa库实现数字签名和验证,将从ECDSA的基本原理出发,详细解析如何在Go语言中实现数字签名和验证,具有一定的参考价值,感兴趣的可以了解一下
    2024-02-02
  • 通过Go channel批量读取数据的示例详解

    通过Go channel批量读取数据的示例详解

    批量处理的主要逻辑是:从 channel 中接收数据,积累到一定数量或者达到时间限制后,将数据批量处理(例如发送到 Kafka 或者写入网络),下面我将展示一个从 Go channel 中批量读取数据,并批量发送到 Kafka 和批量写入网络数据的示例,需要的朋友可以参考下
    2024-10-10
  • 从零封装Gin框架实现日志初始化及切割归档功能

    从零封装Gin框架实现日志初始化及切割归档功能

    这篇文章主要为大家介绍了从零封装Gin框架实现日志初始化及切割归档功能示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2024-01-01
  • logrus日志自定义格式操作

    logrus日志自定义格式操作

    这篇文章主要介绍了logrus日志自定义格式操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-11-11
  • 使用Go语言编写一个NTP服务器的流程步骤

    使用Go语言编写一个NTP服务器的流程步骤

    NTP服务器【Network Time Protocol(NTP)】是用来使计算机时间同步化的一种协议,为了确保封闭局域网内多个服务器的时间同步,我们计划部署一个网络时间同步服务器(NTP服务器),本文给大家介绍了使用Go语言编写一个NTP服务器的流程步骤,需要的朋友可以参考下
    2024-11-11
  • Go语言如何获取goroutine的id

    Go语言如何获取goroutine的id

    在Go语言中,获取 goroutine的id并不像其他编程语言那样容易,但依然有办法,这篇文章就来和大家聊聊具体实现的方法,感兴趣的小伙伴可以了解下
    2024-12-12
  • 一文搞懂Golang中的内存逃逸

    一文搞懂Golang中的内存逃逸

    我们都知道go语言中内存管理工作都是由Go在底层完成的,这样我们可以不用过多的关注底层的内存问题。本文主要总结一下 Golang内存逃逸分析,需要的朋友可以参考以下内容,希望对大家有帮助
    2022-09-09
  • Go中string与[]byte高效互转的方法实例

    Go中string与[]byte高效互转的方法实例

    string与[]byte经常需要互相转化,普通转化会发生底层数据的复制,下面这篇文章主要给大家介绍了关于Go中string与[]byte高效互转的相关资料,文中通过示例代码介绍的非常详细,需要的朋友可以参考下
    2021-09-09
  • Golang简介与基本语法的学习

    Golang简介与基本语法的学习

    这篇文章主要介绍了Golang简介与基本语法的学习,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-04-04
  • Go通过goroutine实现多协程文件上传的基本流程

    Go通过goroutine实现多协程文件上传的基本流程

    多协程文件上传是指利用多线程或多协程技术,同时上传一个或多个文件,以提高上传效率和速度,本文给大家介绍了Go通过goroutine实现多协程文件上传的基本流程,需要的朋友可以参考下
    2024-05-05

最新评论