当前位置:网站首页>Goframe framework: basic auth Middleware
Goframe framework: basic auth Middleware
2022-06-23 17:55:06【Trespass 】
Introduce
Through a complete example , stay gogf/gf Add in microservice Basic Auth middleware .
What is? HTTP Basic Auth middleware ? Basic Auth Middleware will be used for every API Request interception , And verify Basic Auth perhaps X-API-Key Validation of the .
We will use rk-boot To start up gogf/gf Microservices .
rk-boot It's a pass through YAML Start multiple Web Service framework . Please refer to the last chapter of this article , understand rk-boot details .
Please visit the following address for a complete tutorial :https://rkdocs.netlify.app/cn
install
go get github.com/rookie-ninja/rk-boot/gf
Quick start
1. establish boot.yaml
boot.yaml The document describes gogf/gf Meta information required for framework startup .
In order to verify , We launched the following options :
- commonService:commonService It contains a series of general API. details
- interceptors.auth: Basic Auth middleware , The default username and password are user:pass.
--- gf: - name: greeter # Required port: 8080 # Required enabled: true # Required commonService: enabled: true # Optional interceptors: auth: enabled: true # Optional basic: ["user:pass"] # Optional
2. establish main.go
add to /v1/greeter API.
If you want to be in your own API Add Swagger Validation options , Please refer to swag security Official website , We will introduce... In other examples .
// Copyright (c) 2021 rookie-ninja // // Use of this source code is governed by an Apache-style // license that can be found in the LICENSE file. package main import ( "context" "fmt" "github.com/gogf/gf/v2/net/ghttp" "github.com/rookie-ninja/rk-boot" "github.com/rookie-ninja/rk-boot/gf" "net/http" ) // Application entrance. func main() { // Create a new boot instance. boot := rkboot.NewBoot() // Bootstrap boot.Bootstrap(context.Background()) // Register handler gfEntry := rkbootgf.GetGfEntry("greeter") gfEntry.Server.BindHandler("/v1/greeter", func(ctx *ghttp.Request) { ctx.Response.WriteHeader(http.StatusOK) ctx.Response.WriteJson(&GreeterResponse{ Message: fmt.Sprintf("Hello %s!", ctx.GetQuery("name")), }) }) // Wait for shutdown sig boot.WaitForShutdownSig(context.Background()) } type GreeterResponse struct { Message string }
3. Folder structure
$ tree . ├── boot.yaml ├── go.mod ├── go.sum └── main.go 0 directories, 4 files
4. start-up main.go
$ go run main.go 2022-01-04T17:45:56.925+0800 INFO boot/gf_entry.go:1050 Bootstrap gfEntry {"eventId": "984ea465-22cf-4cf3-a734-893fd3dc79e1", "entryName": "greeter"} ------------------------------------------------------------------------ endTime=2022-01-04T17:45:56.925701+08:00 startTime=2022-01-04T17:45:56.924974+08:00 elapsedNano=726802 timezone=CST ids={"eventId":"984ea465-22cf-4cf3-a734-893fd3dc79e1"} app={"appName":"rk","appVersion":"","entryName":"greeter","entryType":"GfEntry"} env={"arch":"amd64","az":"*","domain":"*","hostname":"lark.local","localIP":"10.8.0.2","os":"darwin","realm":"*","region":"*"} payloads={"commonServiceEnabled":true,"commonServicePathPrefix":"/rk/v1/","gfPort":8080} error={} counters={} pairs={} timing={} remoteAddr=localhost operation=Bootstrap resCode=OK eventStatus=Ended EOE
5. verification
Don't offer Basic Auth Under the circumstances , We got 401 Error code .
401
$ curl -X GET localhost:8080/rk/v1/healthy { "error":{ "code":401, "status":"Unauthorized", "message":"Missing authorization, provide one of bellow auth header:[Basic Auth]", "details":[] } } $ curl -X GET "localhost:8080/v1/greeter?name=rk-dev { "error":{ "code":401, "status":"Unauthorized", "message":"Missing authorization, provide one of bellow auth header:[Basic Auth]", "details":[] } }
200
Provide Basic Auth, For safety reasons ,Request Header Inside Auth Need to use Base64 Encoding . We are right. user:pass The string is Base64 code .
$ curl localhost:8080/rk/v1/healthy -H "Authorization: Basic dXNlcjpwYXNz" {"healthy":true} $ curl "localhost:8080/v1/greeter?name=rk-dev" -H "Authorization: Basic dXNlcjpwYXNz" {"Message":"Hello rk-dev!"}
Use X-API-Key to grant authorization
1. modify boot.yaml
This step , We started X-API-Key,key The value of is token.
--- gf: - name: greeter # Required port: 8080 # Required enabled: true # Required commonService: enabled: true # Optional interceptors: auth: enabled: true # Optional apiKey: ["token"] # Optional
2. start-up main.go
$ go run main.go 2022-01-04T17:53:44.120+0800 INFO boot/gf_entry.go:1050 Bootstrap gfEntry {"eventId": "161515d7-d2fb-4457-a24d-590edeb71bdf", "entryName": "greeter"} ------------------------------------------------------------------------ endTime=2022-01-04T17:53:44.12083+08:00 startTime=2022-01-04T17:53:44.120248+08:00 elapsedNano=582008 timezone=CST ids={"eventId":"161515d7-d2fb-4457-a24d-590edeb71bdf"} app={"appName":"rk","appVersion":"","entryName":"greeter","entryType":"GfEntry"} env={"arch":"amd64","az":"*","domain":"*","hostname":"lark.local","localIP":"10.8.0.2","os":"darwin","realm":"*","region":"*"} payloads={"commonServiceEnabled":true,"commonServicePathPrefix":"/rk/v1/","gfPort":8080} error={} counters={} pairs={} timing={} remoteAddr=localhost operation=Bootstrap resCode=OK eventStatus=Ended EOE
3. verification
Same thing , Don't offer X-API-Key Under the circumstances , We got 401 Error code .
401
$ curl localhost:8080/rk/v1/healthy { "error":{ "code":401, "status":"Unauthorized", "message":"Missing authorization, provide one of bellow auth header:[X-API-Key]", "details":[] } } $ curl "localhost:8080/v1/greeter?name=rk-dev" { "error":{ "code":401, "status":"Unauthorized", "message":"Missing authorization, provide one of bellow auth header:[X-API-Key]", "details":[] } }
200
$ curl localhost:8080/rk/v1/healthy -H "X-API-Key: token" {"healthy":true} $ curl "localhost:8080/v1/greeter?name=rk-dev" -H "X-API-Key: token" {"Message":"Hello rk-dev!"}
Ignore request path
We can add a series of API Request path , Let the middleware ignore verifying these API request .
--- gf: - name: greeter # Required port: 8080 # Required enabled: true # Required commonService: enabled: true # Optional interceptors: auth: enabled: true # Optional basic: ["user:pass"] # Optional ignorePrefix: ["/rk/v1/healthy", "/v1/greeter"] # Optional
Swagger UI
How to be in Swagger UI Add in Basic Auth & X-API-Key Input box ?
We use swag Generate Swagger UI The required config file , therefore , Add some... To the code notes .
- stay main() Functions are added as follows annotation, Definition security.
// @securityDefinitions.basic BasicAuth // @securityDefinitions.apikey ApiKeyAuth // @in header // @name X-API-Key
- stay Handler Functions are added as follows annotation.
// @Security ApiKeyAuth // @Security BasicAuth
Complete example
- main.go
// Copyright (c) 2021 rookie-ninja // // Use of this source code is governed by an Apache-style // license that can be found in the LICENSE file. package main import ( "context" "fmt" "github.com/labstack/echo/v4" "github.com/rookie-ninja/rk-boot" "net/http" ) // @title RK Swagger for Echo // @version 1.0 // @description This is a greeter service with rk-boot. // @securityDefinitions.basic BasicAuth // @securityDefinitions.apikey ApiKeyAuth // @in header // @name X-API-Key func main() { // Create a new boot instance. boot := rkboot.NewBoot() // Register handler boot.GetEchoEntry("greeter").Echo.GET("/v1/greeter", Greeter) // Bootstrap boot.Bootstrap(context.Background()) // Wait for shutdown sig boot.WaitForShutdownSig(context.Background()) } // @Summary Greeter service // @Id 1 // @version 1.0 // @produce application/json // @Param name query string true "Input name" // @Security ApiKeyAuth // @Security BasicAuth // @Success 200 {object} GreeterResponse // @Router /v1/greeter [get] func Greeter(ctx echo.Context) error { return ctx.JSON(http.StatusOK, &GreeterResponse{ Message: fmt.Sprintf("Hello %s!", ctx.QueryParam("name")), }) } type GreeterResponse struct { Message string }
- function swag command
$ swag init $ tree . ├── boot.yaml ├── docs │ ├── docs.go │ ├── swagger.json │ └── swagger.yaml ├── go.mod ├── go.sum └── main.go 1 directory, 7 files
- boot.yaml add to sw.enabled & sw.jsonPath (swagger.json Path to file )
--- gf: - name: greeter # Required port: 8080 # Required enabled: true # Required sw: enabled: true # Optional jsonPath: "docs" # Optional interceptors: auth: enabled: true # Optional basic: ["user:pass"] # Optional
function main.go And visit http://localhost:8080/sw
rk-boot Introduce
rk-boot It's a pass through YAML Start multiple Web Service framework .
It's kind of like Spring boot. Through integration rk-xxx Series Library , Can start a variety of Web frame . Of course , Users can also customize rk-xxx The library is integrated into rk-boot in .
rk-boot Bright spot
Through the same format YAML file , Start different Web frame .
such as , We can use the following documents , Start simultaneously in one process gRPC, Gin, Echo, GoFrame frame . Unify the micro service layout within the team .
- Dependent installation
go get github.com/rookie-ninja/rk-boot/grpc go get github.com/rookie-ninja/rk-boot/gin go get github.com/rookie-ninja/rk-boot/echo go get github.com/rookie-ninja/rk-boot/gf
- boot.yaml
--- grpc: - name: grpc-server port: 8080 enabled: true commonService: enabled: true gin: - name: gin-server port: 8081 enabled: true commonService: enabled: true echo: - name: echo-server port: 8082 enabled: true commonService: enabled: true gf: - name: gf-server port: 8083 enabled: true commonService: enabled: true
- main.go
// Copyright (c) 2021 rookie-ninja // // Use of this source code is governed by an Apache-style // license that can be found in the LICENSE file. package main import ( "context" "github.com/rookie-ninja/rk-boot" _ "github.com/rookie-ninja/rk-boot/echo" _ "github.com/rookie-ninja/rk-boot/gf" _ "github.com/rookie-ninja/rk-boot/gin" _ "github.com/rookie-ninja/rk-boot/grpc" ) // Application entrance. func main() { // Create a new boot instance. boot := rkboot.NewBoot() // Bootstrap boot.Bootstrap(context.Background()) // Wait for shutdown sig boot.WaitForShutdownSig(context.Background()) }
- verification
# gRPC throuth grpc-gateway $ curl localhost:8080/rk/v1/healthy {"healthy":true} # Gin $ curl localhost:8081/rk/v1/healthy {"healthy":true} # Echo $ curl localhost:8082/rk/v1/healthy {"healthy":true} # GoFrame $ curl localhost:8083/rk/v1/healthy {"healthy":true}
rk-boot Supported by Web frame
Welcome to contribute new Web Frame to rk-boot In the series .
Reference resources docs&rk-gin As an example .
frame | Development status | install | rely on |
---|---|---|---|
Stable | go get github.com/rookie-ninja/rk-boot/gin | ||
Stable | go get github.com/rookie-ninja/rk-boot/grpc | ||
Stable | go get github.com/rookie-ninja/rk-boot/echo | ||
Stable | go get github.com/rookie-ninja/rk-boot/gf | ||
Testing | go get github.com/rookie-ninja/rk-boot/fiber | ||
Testing | go get github.com/rookie-ninja/rk-boot/zero | ||
Testing | go get github.com/rookie-ninja/rk-boot/mux |
rk-gf Introduce
rk-gf Used by YAML start-up gogf/gf Web service .
Supported features
according to YAML The file initializes the following example , If it's external , Keep the original usage .
example | Introduce |
---|---|
ghttp.Server | Native gogf/gf |
Config | Native spf13/viper Parameter instance |
Logger | Native uber-go/zap Log instance |
EventLogger | Used to record RPC Request log , Use rk-query |
Credential | For remote services , for example ETCD Pull Credential |
Cert | From remote service (ETCD wait ) In order to get TLS/SSL certificate , And start the SSL/TLS |
Prometheus | start-up Prometheus client , And push it to pushgateway |
Swagger | Local boot Swagger UI |
CommonService | Exposure general API |
TV | TV Webpage , Show the basic information of microservices |
StaticFileHandler | start-up Web Form of static file download service , Background storage supports local file systems and pkger. |
Supported middleware
rk-gf Will be based on YAML File initialization middleware .
Middleware | Description |
---|---|
Metrics | collect RPC Metrics, And start the prometheus |
Log | Use rk-query Record each RPC journal |
Trace | collect RPC Call chain , And send data to stdout, Local files or jaeger open-telemetry/opentelemetry-go. |
Panic | Recover from panic for RPC requests and log it. |
Meta | Collect service meta information , Add to return Header in |
Auth | Support Basic Auth & API Key Verification middleware |
RateLimit | RPC Speed limiting middleware |
Timeout | RPC Timeout |
CORS | CORS middleware |
JWT | JWT verification |
Secure | Server side security middleware |
CSRF | CSRF middleware |
GoFrame complete YAML To configure
--- #app: # description: "this is description" # Optional, default: "" # keywords: ["rk", "golang"] # Optional, default: [] # homeUrl: "http://example.com" # Optional, default: "" # iconUrl: "http://example.com" # Optional, default: "" # docsUrl: ["http://example.com"] # Optional, default: [] # maintainers: ["rk-dev"] # Optional, default: [] #zapLogger: # - name: zap-logger # Required # description: "Description of entry" # Optional #eventLogger: # - name: event-logger # Required # description: "Description of entry" # Optional #cred: # - name: "local-cred" # Required # provider: "localFs" # Required, etcd, consul, localFs, remoteFs are supported options # description: "Description of entry" # Optional # locale: "*::*::*::*" # Optional, default: *::*::*::* # paths: # Optional # - "example/boot/full/cred.yaml" #cert: # - name: "local-cert" # Required # provider: "localFs" # Required, etcd, consul, localFs, remoteFs are supported options # description: "Description of entry" # Optional # locale: "*::*::*::*" # Optional, default: *::*::*::* # serverCertPath: "example/boot/full/server.pem" # Optional, default: "", path of certificate on local FS # serverKeyPath: "example/boot/full/server-key.pem" # Optional, default: "", path of certificate on local FS # clientCertPath: "example/client.pem" # Optional, default: "", path of certificate on local FS # clientKeyPath: "example/client.pem" # Optional, default: "", path of certificate on local FS #config: # - name: rk-main # Required # path: "example/boot/full/config.yaml" # Required # locale: "*::*::*::*" # Required, default: *::*::*::* # description: "Description of entry" # Optional gf: - name: greeter # Required port: 8080 # Required enabled: true # Required # description: "greeter server" # Optional, default: "" # cert: # ref: "local-cert" # Optional, default: "", reference of cert entry declared above # sw: # enabled: true # Optional, default: false # path: "sw" # Optional, default: "sw" # jsonPath: "" # Optional # headers: ["sw:rk"] # Optional, default: [] # commonService: # enabled: true # Optional, default: false # static: # enabled: true # Optional, default: false # path: "/rk/v1/static" # Optional, default: /rk/v1/static # sourceType: local # Required, options: pkger, local # sourcePath: "." # Required, full path of source directory # tv: # enabled: true # Optional, default: false # prom: # enabled: true # Optional, default: false # path: "" # Optional, default: "metrics" # pusher: # enabled: false # Optional, default: false # jobName: "greeter-pusher" # Required # remoteAddress: "localhost:9091" # Required # basicAuth: "user:pass" # Optional, default: "" # intervalMs: 10000 # Optional, default: 1000 # cert: # Optional # ref: "local-test" # Optional, default: "", reference of cert entry declared above # logger: # zapLogger: # ref: zap-logger # Optional, default: logger of STDOUT, reference of logger entry declared above # eventLogger: # ref: event-logger # Optional, default: logger of STDOUT, reference of logger entry declared above # interceptors: # loggingZap: # enabled: true # Optional, default: false # zapLoggerEncoding: "json" # Optional, default: "console" # zapLoggerOutputPaths: ["logs/app.log"] # Optional, default: ["stdout"] # eventLoggerEncoding: "json" # Optional, default: "console" # eventLoggerOutputPaths: ["logs/event.log"] # Optional, default: ["stdout"] # metricsProm: # enabled: true # Optional, default: false # auth: # enabled: true # Optional, default: false # basic: # - "user:pass" # Optional, default: [] # ignorePrefix: # - "/rk/v1" # Optional, default: [] # apiKey: # - "keys" # Optional, default: [] # meta: # enabled: true # Optional, default: false # prefix: "rk" # Optional, default: "rk" # tracingTelemetry: # enabled: true # Optional, default: false # exporter: # Optional, default will create a stdout exporter # file: # enabled: true # Optional, default: false # outputPath: "logs/trace.log" # Optional, default: stdout # jaeger: # agent: # enabled: false # Optional, default: false # host: "" # Optional, default: localhost # port: 0 # Optional, default: 6831 # collector: # enabled: true # Optional, default: false # endpoint: "" # Optional, default: http://localhost:14268/api/traces # username: "" # Optional, default: "" # password: "" # Optional, default: "" # rateLimit: # enabled: false # Optional, default: false # algorithm: "leakyBucket" # Optional, default: "tokenBucket" # reqPerSec: 100 # Optional, default: 1000000 # paths: # - path: "/rk/v1/healthy" # Optional, default: "" # reqPerSec: 0 # Optional, default: 1000000 # jwt: # enabled: true # Optional, default: false # signingKey: "my-secret" # Required # ignorePrefix: # Optional, default: [] # - "/rk/v1/tv" # - "/sw" # - "/rk/v1/assets" # signingKeys: # Optional # - "key:value" # signingAlgo: "" # Optional, default: "HS256" # tokenLookup: "header:<name>" # Optional, default: "header:Authorization" # authScheme: "Bearer" # Optional, default: "Bearer" # secure: # enabled: true # Optional, default: false # xssProtection: "" # Optional, default: "1; mode=block" # contentTypeNosniff: "" # Optional, default: nosniff # xFrameOptions: "" # Optional, default: SAMEORIGIN # hstsMaxAge: 0 # Optional, default: 0 # hstsExcludeSubdomains: false # Optional, default: false # hstsPreloadEnabled: false # Optional, default: false # contentSecurityPolicy: "" # Optional, default: "" # cspReportOnly: false # Optional, default: false # referrerPolicy: "" # Optional, default: "" # ignorePrefix: [] # Optional, default: [] # csrf: # enabled: true # tokenLength: 32 # Optional, default: 32 # tokenLookup: "header:X-CSRF-Token" # Optional, default: "header:X-CSRF-Token" # cookieName: "_csrf" # Optional, default: _csrf # cookieDomain: "" # Optional, default: "" # cookiePath: "" # Optional, default: "" # cookieMaxAge: 86400 # Optional, default: 86400 # cookieHttpOnly: false # Optional, default: false # cookieSameSite: "default" # Optional, default: "default", options: lax, strict, none, default # ignorePrefix: [] # Optional, default: []
边栏推荐
- 手机开户一般哪个证券公司好?在线开户安全么?
- Cross browser common events
- Tencent three sides: how to duplicate 4billion QQ numbers?
- Goframe framework: fast implementation of service end flow limiting Middleware
- What is the problem with TS File Error 404 when easynvr plays HLS protocol?
- [JS reverse hundred examples] pedata encryption information and zlib Application of gunzipsync()
- How code 39 check bits are calculated
- Listen attentively and give back sincerely! Pay tribute to the best product people!
- How to quickly obtain and analyze the housing price in your city?
- Petitpotam – NTLM relay to ad CS
猜你喜欢
Explanation of the principle and code implementation analysis of rainbow docking istio
Drawing black technology - easy to build a "real twin" 2D scene
How to make a shirt certificate
High availability solution practice of mongodb advanced applications (4)
Introduction to GTS Academy
Digital intelligent supply chain collaboration solution for new energy industry
How to create a three elimination game
The mail function is normal locally, and the ECS reports an error
POC about secureworks' recent azure Active Directory password brute force vulnerability
Similarities and differences between Chinese and American electronic signature SaaS
随机推荐
- Company offensive operation guide
- Go unit test
- Intelligent supply chain collaborative management solution for logistics industry
- PostgreSQL series articles -- the world's most advanced open source relational database
- Script to view the execution of SQLSERVER database stored procedures
- Transaction processing of cloud development database
- Skills that all applet developers should know: applying applet components
- ACM players take you to play with the array!
- Kotlin invoke convention makes kotlin code more concise
- January 5, 2022: there are four kinds of rhythms: AABB, ABAB and ABB
- Lighthouse open source application practice: o2oa
- . Net cloud native architect training camp (responsibility chain mode) -- learning notes
- Android kotlin exception handling
- Best practices cloud development cloudbase content audit capability
- The principle of MySQL index algorithm and the use of common indexes
- Goframe framework: graceful closing process
- Nanny level teaching! Take you to play with time complexity and space complexity!
- How to design a seckill system - geek course notes
- Method of copying web page content and automatically adding copyright information (compatible with ie, Firefox and chrome)
- [Hyperf]Entry “xxxInterface“ cannot be resolved: the class is not instantiable
- How to use JSON data format
- console. Log() is an asynchronous operation???
- Kdevtmpfsi processing of mining virus -- Practice
- Also using copy and paste to create test data, try the data assistant!
- Async/await
- Programmers are very useful ten tool websites, which are worth collecting
- Troubleshooting and modification process of easycvr interface dislocation in small screen
- Reinforcement learning series (I) -- basic concepts
- Easygbs playback screen is continuously loading. Troubleshooting
- 13. IP address and subnet partitioning (VLSM)
- 12. Manage network environment
- Illustration of mongodb cluster deployment principle (3)
- 6、VLAN
- What if the website is poisoned
- 7、VLAN-Trunk
- Revil - blackmail Virus Emergency Response
- How to make a badge
- Alien world, real presentation, how does the alien version of Pokemon go achieve?
- How to use R language to draw scatter diagram
- How to make validity table