这个比昨晚的要满意,

认证放到中间件那里了。

Mux使用的是gorilla,

中间件使用的是negroni,

启动是用的negroni.classic方法。

package main

import (
	"encoding/json"
	"fmt"
	"io/ioutil"
	"log"
	"net/http"
	"time"

	"github.com/codegangsta/negroni"
	jwt "github.com/dgrijalva/jwt-go"
	"github.com/dgrijalva/jwt-go/request"
	"github.com/gorilla/mux"
)

// using asymmetric crypto/RSA keys
// location of the files used for signing and verification
const (
	privKeyPath = "keys/app.rsa"     // openssl genrsa -out app.rsa 1024
	pubKeyPath  = "keys/app.rsa.pub" // openssl rsa -in app.rsa -pubout > app.rsa.pub
)

const (
	SecretKey = "welcome to wangshubo's blog"
)

// verify key and sign key
var (
	verifyKey, signKey []byte
)

//struct User for parsing login credentials
type User struct {
	UserName string `json:"username"`
	Password string `json:"password"`
}

// read the key files before starting http handlers
func init() {
	var err error
	signKey, err = ioutil.ReadFile(privKeyPath)
	if err != nil {
		log.Fatal("Error reading private key")
		return
	}
	verifyKey, err = ioutil.ReadFile(pubKeyPath)
	if err != nil {
		log.Fatal("Error reading private key")
		return
	}
}

func authMiddleware(w http.ResponseWriter, r *http.Request, next http.HandlerFunc) {
	// validate the token
	pubKey, err := jwt.ParseRSAPublicKeyFromPEM(verifyKey)
	if err != nil {
		fmt.Println("ParseRSAPublicKeyFromPEM:", err.Error())
		return
	}
	token, err := request.ParseFromRequest(r,
		request.AuthorizationHeaderExtractor,
		func(token *jwt.Token) (interface{}, error) {
			// since we only use one private key to sign the tokens,
			// we also only use its public counter part to verify
			return pubKey, nil
		})

	if err == nil && token.Valid {
		next(w, r)
	} else {
		w.WriteHeader(http.StatusUnauthorized)
		fmt.Fprint(w, "Authentication failed")
	}
}

// reads the login credentials, checks them and creates JWT the token
func loginHandler(w http.ResponseWriter, r *http.Request) {
	var user User
	//decode into User struct
	err := json.NewDecoder(r.Body).Decode(&user)
	if err != nil {
		w.WriteHeader(http.StatusInternalServerError)
		fmt.Fprintln(w, "Error in request body")
		return
	}
	log.Println(user.UserName, user.Password)
	// validate user credentials
	if user.UserName != "shijuvar" || user.Password != "pass" {
		w.WriteHeader(http.StatusForbidden)
		fmt.Fprintln(w, "Wrong info")
		return
	}

	// create a signer for rsa 256
	t := jwt.New(jwt.SigningMethodRS256)
	// set our claims
	claims := make(jwt.MapClaims)
	claims["iss"] = "admin"
	claims["CustomUserInfo"] = struct {
		Name string
		Role string
	}{user.UserName, "Member"}
	claims["exp"] = time.Now().Add(time.Minute * 20).Unix()
	t.Claims = claims

	priKey, err := jwt.ParseRSAPrivateKeyFromPEM(signKey)
	if err != nil {
		fmt.Println("ParseRSAPrivateKeyFromPEM:", err.Error())
		return
	}
	tokenString, err := t.SignedString(priKey)
	if err != nil {
		w.WriteHeader(http.StatusInternalServerError)
		fmt.Fprintln(w, "Sorry, error while Signing Token!")

		log.Printf("Token Signing error: %v\n", err)
		return
	}
	response := Token{tokenString}
	jsonResponse(response, w)
}

// only accessible with a valid token
func authHandler(w http.ResponseWriter, r *http.Request) {

	response := Response{"Authorized to the system"}
	jsonResponse(response, w)

}

type Response struct {
	Text string `json:"text"`
}
type Token struct {
	Token string `json:"token"`
}

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)
}

//Entry point of the program
func main() {
	r := mux.NewRouter()
	r.HandleFunc("/login", loginHandler).Methods("POST")
	r.Handle("/auth", negroni.New(
		negroni.HandlerFunc(authMiddleware),
		negroni.Wrap(http.HandlerFunc(authHandler)),
	)).Methods("POST")
	n := negroni.Classic()
	n.UseHandler(r)
	n.Run(":8080")

}

  

《Web Development with Go》JWT认证满意版的更多相关文章

  1. 把旧系统迁移到.Net Core 2.0 日记 (18) --JWT 认证(Json Web Token)

    我们最常用的认证系统是Cookie认证,通常用一般需要人工登录的系统,用户访问授权范围的url时,会自动Redirect到Account/Login,登录后把认证结果存在cookie里. 系统只要找到 ...

  2. Web开发秘方(WEB DEVELOPMENT RECIPES)[47.5MB] PDF扫描版

    不借助插件怎样在移动设备上实现动画效果?怎样快速搭建HTML电子邮箱?怎样制作跨PC和移动设备显示的应用界面?怎样利用最新的JavaScript框架提高应用的响应速度?怎样有效利用CoffeeScri ...

  3. ASP.Net Core 3.0 中使用JWT认证

    JWT认证简单介绍     关于Jwt的介绍网上很多,此处不在赘述,我们主要看看jwt的结构.     JWT主要由三部分组成,如下: HEADER.PAYLOAD.SIGNATURE HEADER包 ...

  4. Dotnet core使用JWT认证授权最佳实践(一)

    最近,团队的小伙伴们在做项目时,需要用到JWT认证.遂根据自己的经验,整理成了这篇文章,用来帮助理清JWT认证的原理和代码编写操作. 一.JWT JSON Web Token (JWT)是一个开放标准 ...

  5. drf的JWT认证

    JWT认证(5星) token发展史 在用户注册或登录后,我们想记录用户的登录状态,或者为用户创建身份认证的凭证.我们不再使用Session认证机制,而使用Json Web Token(本质就是tok ...

  6. 使用python实现后台系统的JWT认证(转)

    今天的文章介绍一种适用于restful+json的API认证方法,这个方法是基于jwt,并且加入了一些从oauth2.0借鉴的改良. 1. 常见的几种实现认证的方法 首先要明白,认证和鉴权是不同的.认 ...

  7. sau交流学习社区--songEagle开发系列:Vue.js + Koa.js项目中使用JWT认证

    一.前言 JWT(JSON Web Token),是为了在网络环境间传递声明而执行的一种基于JSON的开放标准(RFC 7519). JWT不是一个新鲜的东西,网上相关的介绍已经非常多了.不是很了解的 ...

  8. [转]koa 实现 jwt 认证

    本文转自:https://blog.csdn.net/qq673318522/article/details/78641136 关于 Token 认证机制,这里不做更多解释.不清楚的可以看我的这篇文章 ...

  9. Laravel 中使用 JWT 认证的 Restful API

    Laravel 中使用 JWT 认证的 Restful API 5天前/  678 /  3 / 更新于 3天前     在此文章中,我们将学习如何使用 JWT 身份验证在 Laravel 中构建 r ...

随机推荐

  1. STM32调试总结

    1.卡死在这里的问题:没有中断处理函数,程序无法进入中断处理函数.DMA2_Channel3_IRQHandlerDMA2_Channel4_IRQHandlerDMA2_Channel5_IRQHa ...

  2. ARTS-S golang goroutines and channels(二)

    向tcp服务端发消息 package main import ( "io" "log" "net" "os" ) fun ...

  3. ARTS-S golang函数作为参数传递

    函数作为参数传递在单元测试的时候非常有用,看下面的例子. package main import "fmt" func output(f func(string, string, ...

  4. nginx部署基于http负载均衡器

    nginx跨多个应用程序实例的负载平衡是一种用于优化资源利用率,最大化吞吐量,减少延迟和确保容错配置的常用技术. 环境介绍 配置nginx负载均衡器因会用到多台服务器来进行,所以下面我会用到docke ...

  5. Happy Birthday! 今天我 1 周岁生日啦!

    2018.09.28,我第 1 天分享文章. 2019.09.28,我连续分享的第 365 天. 今天我 1 周岁啦! 生日意味着一个新的开端, 意味着重新把握生活的机会. 新的一岁,从新头像开始 愿 ...

  6. 【React】282- 在 React 组件中使用 Refs 指南

    英文:Yomi Eluwande  译文:joking_zhang https://segmentfault.com/a/1190000019277029 使用 React 时,我们的默认思维方式应该 ...

  7. [Java并发] AQS抽象队列同步器源码解析--独占锁释放过程

    [Java并发] AQS抽象队列同步器源码解析--独占锁获取过程 上一篇已经讲解了AQS独占锁的获取过程,接下来就是对AQS独占锁的释放过程进行详细的分析说明,废话不多说,直接进入正文... 锁释放入 ...

  8. CSS让高度百分百的方案

    一般用来上下所有居中,但是这时候auto的计算是全屏像素,从而得到满屏 position: fixed; left: 0px; right: 0px; top: 0px; bottom: 0px; m ...

  9. MYSQL-JDBC批量新增-更新-删除

    目录 1 概述 2 开启MYSQL服务端日志 3 深入MYSQL/JDBC批量插入 3.1 从一个例子出发 3.2 JDBC的批量插入操作 3.3 两个常被忽略的问题 3.5 误区 4 MYSQL/J ...

  10. MySQL如何删除#sql开头的临时表

    1.  现象 巡检时发现服务器磁盘空间不足,通过查看大文件进行筛选是发现有几个#sql开头的文件,且存在超过100G及10G以上的文件. 2. 原因 如果MySQL在一个 ALTER TABLE操作( ...