时间晚了,先来一版调通的JWT普通认证,

明天再弄一个通过中间件,及gorilla,negroni库的认证,

这样正规些,

但认证通过之后,如何对应权限?

由于jwt-go从2升到3,还有rsa 1024加密有对应关系,

真的弄好好久。

一,生成rsa密钥对,必须1024

openssl genrsa -out app.rsa
openssl rsa -in app.rsa -pubout > app.rsa.pub

二,jwt的初始化方法改变

t := jwt.New(jwt.SigningMethodRS512)

  

三,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)
pubKey, err := jwt.ParseRSAPublicKeyFromPEM(verifyKey)

  

五,在认证jwt时,要使用jwt-go的request库,并按规则写好函数

"github.com/dgrijalva/jwt-go/request"
。。。
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
		})

  

六,完整代码:

package main

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

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

// 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.SigningMethodRS512)
	// 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) {
	// 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 {
		switch err.(type) {
		case *jwt.ValidationError: // something was wrong during the validation
			vErr := err.(*jwt.ValidationError)
			switch vErr.Errors {
			case jwt.ValidationErrorExpired:
				w.WriteHeader(http.StatusUnauthorized)
				fmt.Fprintln(w, "Token Expired, get a new one.")
				return
			default:
				w.WriteHeader(http.StatusInternalServerError)
				fmt.Fprintln(w, "Error while Parsing Token!")
				log.Printf("ValidationError error: %+v\n", vErr.Errors)
				return
			}
		default: // something else went wrong
			w.WriteHeader(http.StatusInternalServerError)
			fmt.Fprintln(w, "Error while Parsing Token!")
			log.Printf("Token parse error: %v\n", err)
			return
		}
	}
	if token.Valid {
		response := Response{"Authorized to the system"}
		jsonResponse(response, w)
	} else {
		response := Response{"Invalid token"}
		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.HandleFunc("/auth", authHandler).Methods("POST")
	server := &http.Server{
		Addr:    ":8080",
		Handler: r,
	}
	log.Println("Listening...")
	server.ListenAndServe()
}

  

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

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

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

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

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

  3. Asp.Net Core基于JWT认证的数据接口网关Demo

    近日,应一位朋友的邀请写了个Asp.Net Core基于JWT认证的数据接口网关Demo.朋友自己开了个公司,接到的一个升级项目,客户要求用Aps.Net Core做数据网关服务且基于JWT认证实现对 ...

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

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

  5. JWT 认证 以及Django 中的应用

    jwt 认证 私钥.公钥.CA认证 用一套加密规则 加密和解密 RSA加密 (非对称的加密) 摘要算法:MD5 FTP/互联网下载软件校验MD5 私钥 --RSA算法-->公钥 RSA原理 加密 ...

  6. asp.net core 自定义401和异常显示内容(JWT认证、Cookie Base认证失败显示内容)

    asp.net core 2.0使用JWT认证园子里已经有挺多帖子了,但开发中发现认证未授权情况下返回的401状态码是没有任何信息的,业务中可能有需要返回一串错误的Json信息.在这里我分享一个自定义 ...

  7. Asp.net Core认证和授权:JWT认证和授权

    JWT验证一般用户移动端,因为它不像cookie验证那样,没有授权跳转到登陆页面 JWT是json web token的简称,在  jwt.io 网址可以看到 新建一个API项目,通过postman ...

  8. 如何简单的在 ASP.NET Core 中集成 JWT 认证?

    前情提要:ASP.NET Core 使用 JWT 搭建分布式无状态身份验证系统 文章超长预警(1万字以上),不想看全部实现过程的同学可以直接跳转到末尾查看成果或者一键安装相关的 nuget 包 自上一 ...

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

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

  10. WebApi使用JWT认证(一)

    这是第一部:先实现NetFramework上的WebApi使用JWT认证 1.VS新建一个WebApi项目 2.项目右键----管理Nuget程序包----找到JWT,然后安装 3.Model文件夹下 ...

随机推荐

  1. 决策树(三)决策树与Jupyter小部件的交互式可视化

    简介 决策树是广泛用于分类和回归任务的监督模型. 在本文中,我们将讨论决策树分类器以及如何动态可视化它们. 这些分类器在训练数据上构建一系列简单的if / else规则,通过它们预测目标值.  在本演 ...

  2. 使用iCamera 测试AR0331 300w高分辨率摄像头小结

    使用iCamera 测试AR0331 300w高分辨率摄像头小结 先看下sensor特性 分辨率最高可达:2048*1536=300w像素 1080p帧率最高可达60fps 本次使用usb2,帧率14 ...

  3. 蛋疼的 qii 神马警告才是需要注意的警告?(由于警告引起的截然不同的运行结果)解决总结

    接上文!! 蛋疼一天,折腾一天,没找到具体原因,但是找到了具体操作办法! 1.果断删除没用的文件 特别是sdc文件,旧的没用,果断删除,否则系统会默认使用,带来副作用 2.files 添加系统用到的i ...

  4. 解决老浏览器不支持ES6的方法

    转载地址:http://www.rockyxia.com/?p=669 为什么ES6会有兼容性问题? 由于广大用户使用的浏览器版本在发布的时候也许早于ES6的定稿和发布,而到了今天,我们在编程中如果使 ...

  5. 大数据学习笔记——Linux基本知识及指令(理论部分)

    Linux学习笔记整理 上一篇博客中,我们详细地整理了如何从0部署一套Linux操作系统,那么这一篇就承接上篇文章,我们仔细地把Linux的一些基础知识以及常用指令(包括一小部分高级命令)做一个梳理, ...

  6. docker进阶之路-基础篇 | 二:portainer安装与基本使用

    转载请注明作者及出处: 作者:银河架构师 原文链接:https://www.cnblogs.com/luas/p/12061755.html ​简介 Portainer 是轻量级,跨平台,开源的管理D ...

  7. hdu 5532 Almost Sorted Array (水题)

    Almost Sorted Array Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Ot ...

  8. Day01-基础数据类型/用户交互/流程控制之-if

    1.基础数据类型 什么是数据类型 我们人类可以很容易的分清数字与字符的区别,但是计算机并不能,计算机虽然很强大,但从某种角度上看又很傻,除非你明确的告诉它,1是数字,“汉”是文字,否则它是分不清1和‘ ...

  9. Samba CVE-2017-7494验证实验

    漏洞简介 Samba是在Linux和UNIX系统上实现SMB协议的一个软件,不少IoT设备也使用了Samba.2017年5月24日Samba发布了4.6.4版本,修复了一个严重的远程代码执行漏洞,漏洞 ...

  10. ORA-07217 environment variable cannot be evaluated

    问题描述:还是rman的问题,一个很沙雕的问题,改了半天,准备是要做数据库的全备,和归档的备份 1.连接rman进行备份,这里要保持数据库为mount状态,因为要对数据库全备 [oracle@orcl ...