《Web Development with Go》JWT认证
时间晚了,先来一版调通的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认证的更多相关文章
- 使用python实现后台系统的JWT认证(转)
今天的文章介绍一种适用于restful+json的API认证方法,这个方法是基于jwt,并且加入了一些从oauth2.0借鉴的改良. 1. 常见的几种实现认证的方法 首先要明白,认证和鉴权是不同的.认 ...
- sau交流学习社区--songEagle开发系列:Vue.js + Koa.js项目中使用JWT认证
一.前言 JWT(JSON Web Token),是为了在网络环境间传递声明而执行的一种基于JSON的开放标准(RFC 7519). JWT不是一个新鲜的东西,网上相关的介绍已经非常多了.不是很了解的 ...
- Asp.Net Core基于JWT认证的数据接口网关Demo
近日,应一位朋友的邀请写了个Asp.Net Core基于JWT认证的数据接口网关Demo.朋友自己开了个公司,接到的一个升级项目,客户要求用Aps.Net Core做数据网关服务且基于JWT认证实现对 ...
- Laravel 中使用 JWT 认证的 Restful API
Laravel 中使用 JWT 认证的 Restful API 5天前/ 678 / 3 / 更新于 3天前 在此文章中,我们将学习如何使用 JWT 身份验证在 Laravel 中构建 r ...
- JWT 认证 以及Django 中的应用
jwt 认证 私钥.公钥.CA认证 用一套加密规则 加密和解密 RSA加密 (非对称的加密) 摘要算法:MD5 FTP/互联网下载软件校验MD5 私钥 --RSA算法-->公钥 RSA原理 加密 ...
- asp.net core 自定义401和异常显示内容(JWT认证、Cookie Base认证失败显示内容)
asp.net core 2.0使用JWT认证园子里已经有挺多帖子了,但开发中发现认证未授权情况下返回的401状态码是没有任何信息的,业务中可能有需要返回一串错误的Json信息.在这里我分享一个自定义 ...
- Asp.net Core认证和授权:JWT认证和授权
JWT验证一般用户移动端,因为它不像cookie验证那样,没有授权跳转到登陆页面 JWT是json web token的简称,在 jwt.io 网址可以看到 新建一个API项目,通过postman ...
- 如何简单的在 ASP.NET Core 中集成 JWT 认证?
前情提要:ASP.NET Core 使用 JWT 搭建分布式无状态身份验证系统 文章超长预警(1万字以上),不想看全部实现过程的同学可以直接跳转到末尾查看成果或者一键安装相关的 nuget 包 自上一 ...
- 把旧系统迁移到.Net Core 2.0 日记 (18) --JWT 认证(Json Web Token)
我们最常用的认证系统是Cookie认证,通常用一般需要人工登录的系统,用户访问授权范围的url时,会自动Redirect到Account/Login,登录后把认证结果存在cookie里. 系统只要找到 ...
- WebApi使用JWT认证(一)
这是第一部:先实现NetFramework上的WebApi使用JWT认证 1.VS新建一个WebApi项目 2.项目右键----管理Nuget程序包----找到JWT,然后安装 3.Model文件夹下 ...
随机推荐
- HDU2833-WuKong(求不同起点,终点最短路的交点最多数量)
Liyuan wanted to rewrite the famous book "Journey to the West" ("Xi You Ji" in C ...
- Spring面试题总结及答案
Spring面试总结 Spring是什么? Spring框架是一个java平台,提供全面基础设施支持开发java应用程序. Spring的主要模块有哪些? Spring Code:基础模块,主要提供I ...
- postman接口测试工具的常规使用
目录 postman接口测试工具简介与安装 postman发送get请求 JSON数据详解 postman发送post请求 postman中post请求传参说明 postman设置请求的header ...
- firefox浏览器写xpath
最近在学xpath发现Firefox浏览器不支持xpath定位页面元素 百度为例: F12 页面前端代码 输入最简单的xpath发现并不能定位元素 解决方案:添加 Try Xpath 这个插件,因为 ...
- BBS项目文件
bbs项目文件 # 创建好文件后 git init git remote add origin git@gitee.com:lddragon/bbs3.git git remote git pull ...
- ELK和EFK的区别
ELK 是现阶段众多企业单位都在使用的一种日志分析系统,它能够方便的为我们收集你想要的日志并且展示出来 ELK是Elasticsearch.Logstash.Kibana的简称,这三者都是开源软件,通 ...
- NodeJS4-6静态资源服务器实战_range范围请求
range范围请求:向服务器发起请求可以申明我想请求判断内容的范围,从多少个字节到多少个字节,一次要求把所有的内容拿回来,服务器在得到相应的请求之后,从拿到对应的文件,拿到对应的字节返回给客户端.要实 ...
- 《Dotnet9》系列-开源C# WPF项目1《Accelerider.Windows》强力推荐
时间如流水,只能流去不流回! 点赞再看,养成习惯,这是您给我创作的动力! 本文 Dotnet9 https://dotnet9.com 已收录,站长乐于分享dotnet相关技术,比如Winform.W ...
- C# List集合 GroupBy分组
var grpBalance = listBalance.GroupBy(m => new { m.MerChantId, m.Name}).Distinct().Select(t => ...
- github pages 子域名 ( subdomain ) https 认证
目录 说明 github pages 上的创建子域名 https 认证 说明 转载请注明出处https://www.cnblogs.com/bllovetx/p/12013462.html 欢迎访问我 ...