Skip to content

Instantly share code, notes, and snippets.

@sedkis
Created August 16, 2022 11:19
Show Gist options
  • Save sedkis/0b4a3222ed57cc1a0b55d4c53b0ba10a to your computer and use it in GitHub Desktop.
Save sedkis/0b4a3222ed57cc1a0b55d4c53b0ba10a to your computer and use it in GitHub Desktop.
Go Plugin
  1. compile plugin

  2. load into gateway

  3. use the below YAML:

apiVersion: tyk.tyk.io/v1alpha1
kind: ApiDefinition
metadata:
  name: httpbin-go-auth
spec:
  name: httpbin-go-auth
  use_keyless: false
  protocol: http
  active: true
  use_go_plugin_auth: true
  proxy:
    target_url: http://httpbin.org
    listen_path: /httpbin
    strip_listen_path: true
  custom_middleware:
    driver: goplugin
    pre:
      - name: "AddFooBarHeader"
        path: "/mnt/tyk-gateway/example-go-plugin.so"
    auth_check:
        name: "MyPluginCustomAuthCheck"
        path: "/mnt/tyk-gateway/example-go-plugin.so"

package main
import (
"encoding/json"
"net/http"
"github.com/TykTechnologies/tyk/ctx"
"github.com/TykTechnologies/tyk/user"
"github.com/TykTechnologies/tyk/log"
"github.com/TykTechnologies/tyk/headers"
)
// AddFooBarHeader adds custom "Foo: Bar" header to the request
func AddFooBarHeader(rw http.ResponseWriter, r *http.Request) {
apidef := ctx.GetDefinition(r)
var logger = log.Get()
logger.WithField("api-name", apidef.Name).Info("Processing PRE request in Golang plugin!!" )
r.Header.Add("Foo", "Bar")
}
func getSessionByKey(key string) *user.SessionState {
// here goes our logic to check if passed API key is valid and appropriate key session can be retrieved
// perform auth (only one token "abc" is allowed)
// Here you add code to query your database
if key != "abc" {
return nil
}
// return session
return &user.SessionState{
OrgID: "default",
Alias: "abc-session",
}
}
func MyPluginCustomAuthCheck(rw http.ResponseWriter, r *http.Request) {
apidef := ctx.GetDefinition(r)
var logger = log.Get()
logger.WithField("api-name", apidef.Name).Info("Processing AUTH HTTP request in Golang plugin!!" )
// try to get session by API key
key := r.Header.Get(headers.Authorization)
session := getSessionByKey(key)
if session == nil {
// auth failed, reply with 403
rw.WriteHeader(http.StatusForbidden)
// prepare data to send
replyData := map[string]string{
"reason": "Access forbidden",
}
writeBody(rw, replyData)
//jsonData, err := json.Marshal(replyData)
//if err != nil {
// rw.WriteHeader(http.StatusInternalServerError)
//
// rw.Write(jsonData)
// return
//}
return
}
// auth was successful, add session and key to request's context so other middle-wares can use it
ctx.SetSession(r, session, false, true)
}
func writeBody(rw http.ResponseWriter, replyJson map[string]string) error{
var logger = log.Get()
jsonData, err := json.Marshal(replyJson)
if err != nil {
logger.WithField("replyJson", replyJson).Error("Golang auth plugin: Failed to marshal")
rw.WriteHeader(http.StatusInternalServerError)
return err
}
rw.Write(jsonData)
return nil
}
// called once plugin is loaded, this is where we put all initialization work for plugin
// i.e. setting exported functions, setting up connection pool to storage and etc.
func init() {
var logger = log.Get()
logger.Info("Processing Golang plugin init function version 1.2!!" )
//Here you write the code for db connection
}
func main() {}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment