mirror of
https://github.com/kataras/iris.git
synced 2025-12-30 08:17:18 +00:00
reorganization of _examples and add some new examples such as iris+groupcache+mysql+docker
Former-commit-id: ed635ee95de7160cde11eaabc0c1dcb0e460a620
This commit is contained in:
57
_examples/auth/basicauth/main.go
Normal file
57
_examples/auth/basicauth/main.go
Normal file
@@ -0,0 +1,57 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/kataras/iris/v12"
|
||||
"github.com/kataras/iris/v12/middleware/basicauth"
|
||||
)
|
||||
|
||||
func newApp() *iris.Application {
|
||||
app := iris.New()
|
||||
|
||||
authConfig := basicauth.Config{
|
||||
Users: map[string]string{"myusername": "mypassword", "mySecondusername": "mySecondpassword"},
|
||||
Realm: "Authorization Required", // defaults to "Authorization Required"
|
||||
Expires: time.Duration(30) * time.Minute,
|
||||
}
|
||||
|
||||
authentication := basicauth.New(authConfig)
|
||||
|
||||
// to global app.Use(authentication) (or app.UseGlobal before the .Run)
|
||||
// to routes
|
||||
/*
|
||||
app.Get("/mysecret", authentication, h)
|
||||
*/
|
||||
|
||||
app.Get("/", func(ctx iris.Context) { ctx.Redirect("/admin") })
|
||||
|
||||
// to party
|
||||
|
||||
needAuth := app.Party("/admin", authentication)
|
||||
{
|
||||
//http://localhost:8080/admin
|
||||
needAuth.Get("/", h)
|
||||
// http://localhost:8080/admin/profile
|
||||
needAuth.Get("/profile", h)
|
||||
|
||||
// http://localhost:8080/admin/settings
|
||||
needAuth.Get("/settings", h)
|
||||
}
|
||||
|
||||
return app
|
||||
}
|
||||
|
||||
func main() {
|
||||
app := newApp()
|
||||
// open http://localhost:8080/admin
|
||||
app.Listen(":8080")
|
||||
}
|
||||
|
||||
func h(ctx iris.Context) {
|
||||
username, password, _ := ctx.Request().BasicAuth()
|
||||
// third parameter it will be always true because the middleware
|
||||
// makes sure for that, otherwise this handler will not be executed.
|
||||
|
||||
ctx.Writef("%s %s:%s", ctx.Path(), username, password)
|
||||
}
|
||||
29
_examples/auth/basicauth/main_test.go
Normal file
29
_examples/auth/basicauth/main_test.go
Normal file
@@ -0,0 +1,29 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/kataras/iris/v12/httptest"
|
||||
)
|
||||
|
||||
func TestBasicAuth(t *testing.T) {
|
||||
app := newApp()
|
||||
e := httptest.New(t, app)
|
||||
|
||||
// redirects to /admin without basic auth
|
||||
e.GET("/").Expect().Status(httptest.StatusUnauthorized)
|
||||
// without basic auth
|
||||
e.GET("/admin").Expect().Status(httptest.StatusUnauthorized)
|
||||
|
||||
// with valid basic auth
|
||||
e.GET("/admin").WithBasicAuth("myusername", "mypassword").Expect().
|
||||
Status(httptest.StatusOK).Body().Equal("/admin myusername:mypassword")
|
||||
e.GET("/admin/profile").WithBasicAuth("myusername", "mypassword").Expect().
|
||||
Status(httptest.StatusOK).Body().Equal("/admin/profile myusername:mypassword")
|
||||
e.GET("/admin/settings").WithBasicAuth("myusername", "mypassword").Expect().
|
||||
Status(httptest.StatusOK).Body().Equal("/admin/settings myusername:mypassword")
|
||||
|
||||
// with invalid basic auth
|
||||
e.GET("/admin/settings").WithBasicAuth("invalidusername", "invalidpassword").
|
||||
Expect().Status(httptest.StatusUnauthorized)
|
||||
}
|
||||
407
_examples/auth/goth/main.go
Normal file
407
_examples/auth/goth/main.go
Normal file
@@ -0,0 +1,407 @@
|
||||
package main
|
||||
|
||||
// Any OAuth2 (even the pure golang/x/net/oauth2) package
|
||||
// can be used with iris but at this example we will see the markbates' goth:
|
||||
//
|
||||
// $ go get github.com/markbates/goth/...
|
||||
//
|
||||
// This OAuth2 example works with sessions, so we will need
|
||||
// to attach a session manager.
|
||||
// Optionally: for even more secure session values,
|
||||
// developers can use any third-party package to add a custom cookie encoder/decoder.
|
||||
// At this example we will use the gorilla's securecookie:
|
||||
//
|
||||
// $ go get github.com/gorilla/securecookie
|
||||
// Example of securecookie can be found at "sessions/securecookie" example folder.
|
||||
|
||||
// Notes:
|
||||
// The whole example is converted by markbates/goth/example/main.go.
|
||||
// It's tested with my own TWITTER application and it worked, even for localhost.
|
||||
// I guess that everything else works as expected, all bugs reported by goth library's community
|
||||
// are fixed in the time I wrote that example, have fun!
|
||||
import (
|
||||
"errors"
|
||||
"os"
|
||||
"sort"
|
||||
|
||||
"github.com/kataras/iris/v12"
|
||||
|
||||
"github.com/kataras/iris/v12/sessions"
|
||||
|
||||
"github.com/gorilla/securecookie" // optionally, used for session's encoder/decoder
|
||||
|
||||
"github.com/markbates/goth"
|
||||
"github.com/markbates/goth/providers/amazon"
|
||||
"github.com/markbates/goth/providers/auth0"
|
||||
"github.com/markbates/goth/providers/bitbucket"
|
||||
"github.com/markbates/goth/providers/box"
|
||||
"github.com/markbates/goth/providers/dailymotion"
|
||||
"github.com/markbates/goth/providers/deezer"
|
||||
"github.com/markbates/goth/providers/digitalocean"
|
||||
"github.com/markbates/goth/providers/discord"
|
||||
"github.com/markbates/goth/providers/dropbox"
|
||||
"github.com/markbates/goth/providers/facebook"
|
||||
"github.com/markbates/goth/providers/fitbit"
|
||||
"github.com/markbates/goth/providers/github"
|
||||
"github.com/markbates/goth/providers/gitlab"
|
||||
"github.com/markbates/goth/providers/gplus"
|
||||
"github.com/markbates/goth/providers/heroku"
|
||||
"github.com/markbates/goth/providers/instagram"
|
||||
"github.com/markbates/goth/providers/intercom"
|
||||
"github.com/markbates/goth/providers/lastfm"
|
||||
"github.com/markbates/goth/providers/linkedin"
|
||||
"github.com/markbates/goth/providers/meetup"
|
||||
"github.com/markbates/goth/providers/onedrive"
|
||||
"github.com/markbates/goth/providers/openidConnect"
|
||||
"github.com/markbates/goth/providers/paypal"
|
||||
"github.com/markbates/goth/providers/salesforce"
|
||||
"github.com/markbates/goth/providers/slack"
|
||||
"github.com/markbates/goth/providers/soundcloud"
|
||||
"github.com/markbates/goth/providers/spotify"
|
||||
"github.com/markbates/goth/providers/steam"
|
||||
"github.com/markbates/goth/providers/stripe"
|
||||
"github.com/markbates/goth/providers/twitch"
|
||||
"github.com/markbates/goth/providers/twitter"
|
||||
"github.com/markbates/goth/providers/uber"
|
||||
"github.com/markbates/goth/providers/wepay"
|
||||
"github.com/markbates/goth/providers/xero"
|
||||
"github.com/markbates/goth/providers/yahoo"
|
||||
"github.com/markbates/goth/providers/yammer"
|
||||
)
|
||||
|
||||
var sessionsManager *sessions.Sessions
|
||||
|
||||
func init() {
|
||||
// attach a session manager
|
||||
cookieName := "mycustomsessionid"
|
||||
hashKey := securecookie.GenerateRandomKey(64)
|
||||
blockKey := securecookie.GenerateRandomKey(32)
|
||||
secureCookie := securecookie.New(hashKey, blockKey)
|
||||
|
||||
sessionsManager = sessions.New(sessions.Config{
|
||||
Cookie: cookieName,
|
||||
Encoding: secureCookie,
|
||||
AllowReclaim: true,
|
||||
})
|
||||
}
|
||||
|
||||
// These are some function helpers that you may use if you want
|
||||
|
||||
// GetProviderName is a function used to get the name of a provider
|
||||
// for a given request. By default, this provider is fetched from
|
||||
// the URL query string. If you provide it in a different way,
|
||||
// assign your own function to this variable that returns the provider
|
||||
// name for your request.
|
||||
var GetProviderName = func(ctx iris.Context) (string, error) {
|
||||
// try to get it from the url param "provider"
|
||||
if p := ctx.URLParam("provider"); p != "" {
|
||||
return p, nil
|
||||
}
|
||||
|
||||
// try to get it from the url PATH parameter "{provider} or :provider or {provider:string} or {provider:alphabetical}"
|
||||
if p := ctx.Params().Get("provider"); p != "" {
|
||||
return p, nil
|
||||
}
|
||||
|
||||
// try to get it from context's per-request storage
|
||||
if p := ctx.Values().GetString("provider"); p != "" {
|
||||
return p, nil
|
||||
}
|
||||
// if not found then return an empty string with the corresponding error
|
||||
return "", errors.New("you must select a provider")
|
||||
}
|
||||
|
||||
/*
|
||||
BeginAuthHandler is a convenience handler for starting the authentication process.
|
||||
It expects to be able to get the name of the provider from the query parameters
|
||||
as either "provider" or ":provider".
|
||||
|
||||
BeginAuthHandler will redirect the user to the appropriate authentication end-point
|
||||
for the requested provider.
|
||||
|
||||
See https://github.com/markbates/goth/examples/main.go to see this in action.
|
||||
*/
|
||||
func BeginAuthHandler(ctx iris.Context) {
|
||||
url, err := GetAuthURL(ctx)
|
||||
if err != nil {
|
||||
ctx.StatusCode(iris.StatusBadRequest)
|
||||
ctx.Writef("%v", err)
|
||||
return
|
||||
}
|
||||
|
||||
ctx.Redirect(url, iris.StatusTemporaryRedirect)
|
||||
}
|
||||
|
||||
/*
|
||||
GetAuthURL starts the authentication process with the requested provided.
|
||||
It will return a URL that should be used to send users to.
|
||||
|
||||
It expects to be able to get the name of the provider from the query parameters
|
||||
as either "provider" or ":provider" or from the context's value of "provider" key.
|
||||
|
||||
I would recommend using the BeginAuthHandler instead of doing all of these steps
|
||||
yourself, but that's entirely up to you.
|
||||
*/
|
||||
func GetAuthURL(ctx iris.Context) (string, error) {
|
||||
providerName, err := GetProviderName(ctx)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
provider, err := goth.GetProvider(providerName)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
sess, err := provider.BeginAuth(SetState(ctx))
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
url, err := sess.GetAuthURL()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
session := sessionsManager.Start(ctx)
|
||||
session.Set(providerName, sess.Marshal())
|
||||
return url, nil
|
||||
}
|
||||
|
||||
// SetState sets the state string associated with the given request.
|
||||
// If no state string is associated with the request, one will be generated.
|
||||
// This state is sent to the provider and can be retrieved during the
|
||||
// callback.
|
||||
var SetState = func(ctx iris.Context) string {
|
||||
state := ctx.URLParam("state")
|
||||
if len(state) > 0 {
|
||||
return state
|
||||
}
|
||||
|
||||
return "state"
|
||||
}
|
||||
|
||||
// GetState gets the state returned by the provider during the callback.
|
||||
// This is used to prevent CSRF attacks, see
|
||||
// http://tools.ietf.org/html/rfc6749#section-10.12
|
||||
var GetState = func(ctx iris.Context) string {
|
||||
return ctx.URLParam("state")
|
||||
}
|
||||
|
||||
/*
|
||||
CompleteUserAuth does what it says on the tin. It completes the authentication
|
||||
process and fetches all of the basic information about the user from the provider.
|
||||
|
||||
It expects to be able to get the name of the provider from the query parameters
|
||||
as either "provider" or ":provider".
|
||||
|
||||
See https://github.com/markbates/goth/examples/main.go to see this in action.
|
||||
*/
|
||||
var CompleteUserAuth = func(ctx iris.Context) (goth.User, error) {
|
||||
providerName, err := GetProviderName(ctx)
|
||||
if err != nil {
|
||||
return goth.User{}, err
|
||||
}
|
||||
|
||||
provider, err := goth.GetProvider(providerName)
|
||||
if err != nil {
|
||||
return goth.User{}, err
|
||||
}
|
||||
session := sessionsManager.Start(ctx)
|
||||
value := session.GetString(providerName)
|
||||
if value == "" {
|
||||
return goth.User{}, errors.New("session value for " + providerName + " not found")
|
||||
}
|
||||
|
||||
sess, err := provider.UnmarshalSession(value)
|
||||
if err != nil {
|
||||
return goth.User{}, err
|
||||
}
|
||||
|
||||
user, err := provider.FetchUser(sess)
|
||||
if err == nil {
|
||||
// user can be found with existing session data
|
||||
return user, err
|
||||
}
|
||||
|
||||
// get new token and retry fetch
|
||||
_, err = sess.Authorize(provider, ctx.Request().URL.Query())
|
||||
if err != nil {
|
||||
return goth.User{}, err
|
||||
}
|
||||
|
||||
session.Set(providerName, sess.Marshal())
|
||||
return provider.FetchUser(sess)
|
||||
}
|
||||
|
||||
// Logout invalidates a user session.
|
||||
func Logout(ctx iris.Context) error {
|
||||
providerName, err := GetProviderName(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
session := sessionsManager.Start(ctx)
|
||||
session.Delete(providerName)
|
||||
return nil
|
||||
}
|
||||
|
||||
// End of the "some function helpers".
|
||||
|
||||
func main() {
|
||||
goth.UseProviders(
|
||||
twitter.New(os.Getenv("TWITTER_KEY"), os.Getenv("TWITTER_SECRET"), "http://localhost:3000/auth/twitter/callback"),
|
||||
// If you'd like to use authenticate instead of authorize in Twitter provider, use this instead.
|
||||
// twitter.NewAuthenticate(os.Getenv("TWITTER_KEY"), os.Getenv("TWITTER_SECRET"), "http://localhost:3000/auth/twitter/callback"),
|
||||
|
||||
facebook.New(os.Getenv("FACEBOOK_KEY"), os.Getenv("FACEBOOK_SECRET"), "http://localhost:3000/auth/facebook/callback"),
|
||||
fitbit.New(os.Getenv("FITBIT_KEY"), os.Getenv("FITBIT_SECRET"), "http://localhost:3000/auth/fitbit/callback"),
|
||||
gplus.New(os.Getenv("GPLUS_KEY"), os.Getenv("GPLUS_SECRET"), "http://localhost:3000/auth/gplus/callback"),
|
||||
github.New(os.Getenv("GITHUB_KEY"), os.Getenv("GITHUB_SECRET"), "http://localhost:3000/auth/github/callback"),
|
||||
spotify.New(os.Getenv("SPOTIFY_KEY"), os.Getenv("SPOTIFY_SECRET"), "http://localhost:3000/auth/spotify/callback"),
|
||||
linkedin.New(os.Getenv("LINKEDIN_KEY"), os.Getenv("LINKEDIN_SECRET"), "http://localhost:3000/auth/linkedin/callback"),
|
||||
lastfm.New(os.Getenv("LASTFM_KEY"), os.Getenv("LASTFM_SECRET"), "http://localhost:3000/auth/lastfm/callback"),
|
||||
twitch.New(os.Getenv("TWITCH_KEY"), os.Getenv("TWITCH_SECRET"), "http://localhost:3000/auth/twitch/callback"),
|
||||
dropbox.New(os.Getenv("DROPBOX_KEY"), os.Getenv("DROPBOX_SECRET"), "http://localhost:3000/auth/dropbox/callback"),
|
||||
digitalocean.New(os.Getenv("DIGITALOCEAN_KEY"), os.Getenv("DIGITALOCEAN_SECRET"), "http://localhost:3000/auth/digitalocean/callback", "read"),
|
||||
bitbucket.New(os.Getenv("BITBUCKET_KEY"), os.Getenv("BITBUCKET_SECRET"), "http://localhost:3000/auth/bitbucket/callback"),
|
||||
instagram.New(os.Getenv("INSTAGRAM_KEY"), os.Getenv("INSTAGRAM_SECRET"), "http://localhost:3000/auth/instagram/callback"),
|
||||
intercom.New(os.Getenv("INTERCOM_KEY"), os.Getenv("INTERCOM_SECRET"), "http://localhost:3000/auth/intercom/callback"),
|
||||
box.New(os.Getenv("BOX_KEY"), os.Getenv("BOX_SECRET"), "http://localhost:3000/auth/box/callback"),
|
||||
salesforce.New(os.Getenv("SALESFORCE_KEY"), os.Getenv("SALESFORCE_SECRET"), "http://localhost:3000/auth/salesforce/callback"),
|
||||
amazon.New(os.Getenv("AMAZON_KEY"), os.Getenv("AMAZON_SECRET"), "http://localhost:3000/auth/amazon/callback"),
|
||||
yammer.New(os.Getenv("YAMMER_KEY"), os.Getenv("YAMMER_SECRET"), "http://localhost:3000/auth/yammer/callback"),
|
||||
onedrive.New(os.Getenv("ONEDRIVE_KEY"), os.Getenv("ONEDRIVE_SECRET"), "http://localhost:3000/auth/onedrive/callback"),
|
||||
|
||||
// Pointed localhost.com to http://localhost:3000/auth/yahoo/callback through proxy as yahoo
|
||||
// does not allow to put custom ports in redirection uri
|
||||
yahoo.New(os.Getenv("YAHOO_KEY"), os.Getenv("YAHOO_SECRET"), "http://localhost.com"),
|
||||
slack.New(os.Getenv("SLACK_KEY"), os.Getenv("SLACK_SECRET"), "http://localhost:3000/auth/slack/callback"),
|
||||
stripe.New(os.Getenv("STRIPE_KEY"), os.Getenv("STRIPE_SECRET"), "http://localhost:3000/auth/stripe/callback"),
|
||||
wepay.New(os.Getenv("WEPAY_KEY"), os.Getenv("WEPAY_SECRET"), "http://localhost:3000/auth/wepay/callback", "view_user"),
|
||||
// By default paypal production auth urls will be used, please set PAYPAL_ENV=sandbox as environment variable for testing
|
||||
// in sandbox environment
|
||||
paypal.New(os.Getenv("PAYPAL_KEY"), os.Getenv("PAYPAL_SECRET"), "http://localhost:3000/auth/paypal/callback"),
|
||||
steam.New(os.Getenv("STEAM_KEY"), "http://localhost:3000/auth/steam/callback"),
|
||||
heroku.New(os.Getenv("HEROKU_KEY"), os.Getenv("HEROKU_SECRET"), "http://localhost:3000/auth/heroku/callback"),
|
||||
uber.New(os.Getenv("UBER_KEY"), os.Getenv("UBER_SECRET"), "http://localhost:3000/auth/uber/callback"),
|
||||
soundcloud.New(os.Getenv("SOUNDCLOUD_KEY"), os.Getenv("SOUNDCLOUD_SECRET"), "http://localhost:3000/auth/soundcloud/callback"),
|
||||
gitlab.New(os.Getenv("GITLAB_KEY"), os.Getenv("GITLAB_SECRET"), "http://localhost:3000/auth/gitlab/callback"),
|
||||
dailymotion.New(os.Getenv("DAILYMOTION_KEY"), os.Getenv("DAILYMOTION_SECRET"), "http://localhost:3000/auth/dailymotion/callback", "email"),
|
||||
deezer.New(os.Getenv("DEEZER_KEY"), os.Getenv("DEEZER_SECRET"), "http://localhost:3000/auth/deezer/callback", "email"),
|
||||
discord.New(os.Getenv("DISCORD_KEY"), os.Getenv("DISCORD_SECRET"), "http://localhost:3000/auth/discord/callback", discord.ScopeIdentify, discord.ScopeEmail),
|
||||
meetup.New(os.Getenv("MEETUP_KEY"), os.Getenv("MEETUP_SECRET"), "http://localhost:3000/auth/meetup/callback"),
|
||||
|
||||
// Auth0 allocates domain per customer, a domain must be provided for auth0 to work
|
||||
auth0.New(os.Getenv("AUTH0_KEY"), os.Getenv("AUTH0_SECRET"), "http://localhost:3000/auth/auth0/callback", os.Getenv("AUTH0_DOMAIN")),
|
||||
xero.New(os.Getenv("XERO_KEY"), os.Getenv("XERO_SECRET"), "http://localhost:3000/auth/xero/callback"),
|
||||
)
|
||||
|
||||
// OpenID Connect is based on OpenID Connect Auto Discovery URL (https://openid.net/specs/openid-connect-discovery-1_0-17.html)
|
||||
// because the OpenID Connect provider initialize it self in the New(), it can return an error which should be handled or ignored
|
||||
// ignore the error for now
|
||||
openidConnect, _ := openidConnect.New(os.Getenv("OPENID_CONNECT_KEY"), os.Getenv("OPENID_CONNECT_SECRET"), "http://localhost:3000/auth/openid-connect/callback", os.Getenv("OPENID_CONNECT_DISCOVERY_URL"))
|
||||
if openidConnect != nil {
|
||||
goth.UseProviders(openidConnect)
|
||||
}
|
||||
|
||||
m := make(map[string]string)
|
||||
m["amazon"] = "Amazon"
|
||||
m["bitbucket"] = "Bitbucket"
|
||||
m["box"] = "Box"
|
||||
m["dailymotion"] = "Dailymotion"
|
||||
m["deezer"] = "Deezer"
|
||||
m["digitalocean"] = "Digital Ocean"
|
||||
m["discord"] = "Discord"
|
||||
m["dropbox"] = "Dropbox"
|
||||
m["facebook"] = "Facebook"
|
||||
m["fitbit"] = "Fitbit"
|
||||
m["github"] = "Github"
|
||||
m["gitlab"] = "Gitlab"
|
||||
m["soundcloud"] = "SoundCloud"
|
||||
m["spotify"] = "Spotify"
|
||||
m["steam"] = "Steam"
|
||||
m["stripe"] = "Stripe"
|
||||
m["twitch"] = "Twitch"
|
||||
m["uber"] = "Uber"
|
||||
m["wepay"] = "Wepay"
|
||||
m["yahoo"] = "Yahoo"
|
||||
m["yammer"] = "Yammer"
|
||||
m["gplus"] = "Google Plus"
|
||||
m["heroku"] = "Heroku"
|
||||
m["instagram"] = "Instagram"
|
||||
m["intercom"] = "Intercom"
|
||||
m["lastfm"] = "Last FM"
|
||||
m["linkedin"] = "Linkedin"
|
||||
m["onedrive"] = "Onedrive"
|
||||
m["paypal"] = "Paypal"
|
||||
m["twitter"] = "Twitter"
|
||||
m["salesforce"] = "Salesforce"
|
||||
m["slack"] = "Slack"
|
||||
m["meetup"] = "Meetup.com"
|
||||
m["auth0"] = "Auth0"
|
||||
m["openid-connect"] = "OpenID Connect"
|
||||
m["xero"] = "Xero"
|
||||
|
||||
var keys []string
|
||||
for k := range m {
|
||||
keys = append(keys, k)
|
||||
}
|
||||
sort.Strings(keys)
|
||||
|
||||
providerIndex := &ProviderIndex{Providers: keys, ProvidersMap: m}
|
||||
|
||||
// create our app,
|
||||
// set a view
|
||||
// set sessions
|
||||
// and setup the router for the showcase
|
||||
app := iris.New()
|
||||
|
||||
// attach and build our templates
|
||||
app.RegisterView(iris.HTML("./templates", ".html"))
|
||||
|
||||
// start of the router
|
||||
|
||||
app.Get("/auth/{provider}/callback", func(ctx iris.Context) {
|
||||
user, err := CompleteUserAuth(ctx)
|
||||
if err != nil {
|
||||
ctx.StatusCode(iris.StatusInternalServerError)
|
||||
ctx.Writef("%v", err)
|
||||
return
|
||||
}
|
||||
ctx.ViewData("", user)
|
||||
if err := ctx.View("user.html"); err != nil {
|
||||
ctx.Writef("%v", err)
|
||||
}
|
||||
})
|
||||
|
||||
app.Get("/logout/{provider}", func(ctx iris.Context) {
|
||||
Logout(ctx)
|
||||
ctx.Redirect("/", iris.StatusTemporaryRedirect)
|
||||
})
|
||||
|
||||
app.Get("/auth/{provider}", func(ctx iris.Context) {
|
||||
// try to get the user without re-authenticating
|
||||
if gothUser, err := CompleteUserAuth(ctx); err == nil {
|
||||
ctx.ViewData("", gothUser)
|
||||
if err := ctx.View("user.html"); err != nil {
|
||||
ctx.Writef("%v", err)
|
||||
}
|
||||
} else {
|
||||
BeginAuthHandler(ctx)
|
||||
}
|
||||
})
|
||||
|
||||
app.Get("/", func(ctx iris.Context) {
|
||||
ctx.ViewData("", providerIndex)
|
||||
|
||||
if err := ctx.View("index.html"); err != nil {
|
||||
ctx.Writef("%v", err)
|
||||
}
|
||||
})
|
||||
|
||||
// http://localhost:3000
|
||||
app.Listen("localhost:3000")
|
||||
}
|
||||
|
||||
type ProviderIndex struct {
|
||||
Providers []string
|
||||
ProvidersMap map[string]string
|
||||
}
|
||||
3
_examples/auth/goth/templates/index.html
Normal file
3
_examples/auth/goth/templates/index.html
Normal file
@@ -0,0 +1,3 @@
|
||||
{{range $key,$value:=.Providers}}
|
||||
<p><a href="/auth/{{$value}}">Log in with {{index $.ProvidersMap $value}}</a></p>
|
||||
{{end}}
|
||||
11
_examples/auth/goth/templates/user.html
Normal file
11
_examples/auth/goth/templates/user.html
Normal file
@@ -0,0 +1,11 @@
|
||||
<p><a href="/logout/{{.Provider}}">logout</a></p>
|
||||
<p>Name: {{.Name}} [{{.LastName}}, {{.FirstName}}]</p>
|
||||
<p>Email: {{.Email}}</p>
|
||||
<p>NickName: {{.NickName}}</p>
|
||||
<p>Location: {{.Location}}</p>
|
||||
<p>AvatarURL: {{.AvatarURL}} <img src="{{.AvatarURL}}"></p>
|
||||
<p>Description: {{.Description}}</p>
|
||||
<p>UserID: {{.UserID}}</p>
|
||||
<p>AccessToken: {{.AccessToken}}</p>
|
||||
<p>ExpiresAt: {{.ExpiresAt}}</p>
|
||||
<p>RefreshToken: {{.RefreshToken}}</p>
|
||||
3
_examples/auth/hcaptcha/hosts
Normal file
3
_examples/auth/hcaptcha/hosts
Normal file
@@ -0,0 +1,3 @@
|
||||
# https://docs.hcaptcha.com/#localdev
|
||||
# Add to the end of your hosts file, e.g. on windows: C:/windows/system32/drivers/etc/hosts
|
||||
127.0.0.1 yourdomain.com
|
||||
46
_examples/auth/hcaptcha/main.go
Normal file
46
_examples/auth/hcaptcha/main.go
Normal file
@@ -0,0 +1,46 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"os"
|
||||
|
||||
"github.com/kataras/iris/v12"
|
||||
"github.com/kataras/iris/v12/middleware/hcaptcha"
|
||||
)
|
||||
|
||||
// Get the following values from: https://dashboard.hcaptcha.com
|
||||
// Also, check: https://docs.hcaptcha.com/#localdev to test on local environment.
|
||||
var (
|
||||
siteKey = os.Getenv("HCAPTCHA-SITE-KEY")
|
||||
secretKey = os.Getenv("HCAPTCHA-SECRET-KEY")
|
||||
)
|
||||
|
||||
func main() {
|
||||
app := iris.New()
|
||||
app.RegisterView(iris.HTML("./templates", ".html"))
|
||||
|
||||
hCaptcha := hcaptcha.New(secretKey)
|
||||
app.Get("/register", registerForm)
|
||||
app.Post("/register", hCaptcha, register) // See `hcaptcha.SiteVerify` for manual validation too.
|
||||
|
||||
app.Logger().Infof("SiteKey = %s\tSecretKey = %s",
|
||||
siteKey, secretKey)
|
||||
|
||||
// GET: http://yourdomain.com/register
|
||||
app.Listen(":80")
|
||||
}
|
||||
|
||||
func register(ctx iris.Context) {
|
||||
hcaptchaResp, ok := hcaptcha.Get(ctx)
|
||||
if !ok {
|
||||
ctx.StatusCode(iris.StatusUnauthorized)
|
||||
ctx.WriteString("Are you a bot?")
|
||||
return
|
||||
}
|
||||
|
||||
ctx.Writef("Register action here...action was asked by a Human.\nResponse value is: %#+v", hcaptchaResp)
|
||||
}
|
||||
|
||||
func registerForm(ctx iris.Context) {
|
||||
ctx.ViewData("SiteKey", siteKey)
|
||||
ctx.View("register_form.html")
|
||||
}
|
||||
18
_examples/auth/hcaptcha/templates/register_form.html
Normal file
18
_examples/auth/hcaptcha/templates/register_form.html
Normal file
@@ -0,0 +1,18 @@
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<title>hCaptcha Demo</title>
|
||||
<script src="https://hcaptcha.com/1/api.js" async defer></script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<form action="/register" method="POST">
|
||||
<input type="text" name="email" placeholder="Email" />
|
||||
<input type="password" name="password" placeholder="Password" />
|
||||
<div class="h-captcha" data-sitekey="{{ .SiteKey }}"></div>
|
||||
<br />
|
||||
<input type="submit" value="Submit" />
|
||||
</form>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
29
_examples/auth/jwt/README.md
Normal file
29
_examples/auth/jwt/README.md
Normal file
@@ -0,0 +1,29 @@
|
||||
# Generate RSA
|
||||
|
||||
```sh
|
||||
$ openssl genrsa -des3 -out private_rsa.pem 2048
|
||||
```
|
||||
|
||||
```go
|
||||
b, err := ioutil.ReadFile("./private_rsa.pem")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
key := jwt.MustParseRSAPrivateKey(b, []byte("pass"))
|
||||
```
|
||||
|
||||
OR
|
||||
|
||||
```go
|
||||
import "crypto/rand"
|
||||
import "crypto/rsa"
|
||||
|
||||
key, err := rsa.GenerateKey(rand.Reader, 2048)
|
||||
```
|
||||
|
||||
# Generate Ed25519
|
||||
|
||||
```sh
|
||||
$ openssl genpkey -algorithm Ed25519 -out private_ed25519.pem
|
||||
$ openssl req -x509 -key private_ed25519.pem -out cert_ed25519.pem -days 365
|
||||
```
|
||||
155
_examples/auth/jwt/main.go
Normal file
155
_examples/auth/jwt/main.go
Normal file
@@ -0,0 +1,155 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/kataras/iris/v12"
|
||||
"github.com/kataras/iris/v12/middleware/jwt"
|
||||
)
|
||||
|
||||
// UserClaims a custom claims structure. You can just use jwt.Claims too.
|
||||
type UserClaims struct {
|
||||
jwt.Claims
|
||||
Username string
|
||||
}
|
||||
|
||||
func main() {
|
||||
// Get keys from system's environment variables
|
||||
// JWT_SECRET (for signing and verification) and JWT_SECRET_ENC(for encryption and decryption),
|
||||
// or defaults to "secret" and "itsa16bytesecret" respectfully.
|
||||
//
|
||||
// Use the `jwt.New` instead for more flexibility, if necessary.
|
||||
j := jwt.HMAC(15*time.Minute, "secret", "itsa16bytesecret")
|
||||
|
||||
app := iris.New()
|
||||
app.Logger().SetLevel("debug")
|
||||
|
||||
app.Get("/authenticate", func(ctx iris.Context) {
|
||||
standardClaims := jwt.Claims{Issuer: "an-issuer", Audience: jwt.Audience{"an-audience"}}
|
||||
// NOTE: if custom claims then the `j.Expiry(claims)` (or jwt.Expiry(duration, claims))
|
||||
// MUST be called in order to set the expiration time.
|
||||
customClaims := UserClaims{
|
||||
Claims: j.Expiry(standardClaims),
|
||||
Username: "kataras",
|
||||
}
|
||||
|
||||
j.WriteToken(ctx, customClaims)
|
||||
})
|
||||
|
||||
userRouter := app.Party("/user")
|
||||
{
|
||||
// userRouter.Use(j.Verify)
|
||||
// userRouter.Get("/", func(ctx iris.Context) {
|
||||
// var claims UserClaims
|
||||
// if err := jwt.ReadClaims(ctx, &claims); err != nil {
|
||||
// // Validation-only errors, the rest are already
|
||||
// // checked on `j.Verify` middleware.
|
||||
// ctx.StopWithStatus(iris.StatusUnauthorized)
|
||||
// return
|
||||
// }
|
||||
//
|
||||
// ctx.Writef("Claims: %#+v\n", claims)
|
||||
// })
|
||||
//
|
||||
// OR:
|
||||
userRouter.Get("/", func(ctx iris.Context) {
|
||||
var claims UserClaims
|
||||
if err := j.VerifyToken(ctx, &claims); err != nil {
|
||||
ctx.StopWithStatus(iris.StatusUnauthorized)
|
||||
return
|
||||
}
|
||||
|
||||
ctx.Writef("Claims: %#+v\n", claims)
|
||||
})
|
||||
}
|
||||
|
||||
app.Listen(":8080")
|
||||
}
|
||||
|
||||
/*
|
||||
func default_RSA_Example() {
|
||||
j := jwt.RSA(15*time.Minute)
|
||||
}
|
||||
|
||||
Same as:
|
||||
|
||||
func load_File_Or_Generate_RSA_Example() {
|
||||
signKey, err := jwt.LoadRSA("jwt_sign.key", 2048)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
j, err := jwt.New(15*time.Minute, jwt.RS256, signKey)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
encKey, err := jwt.LoadRSA("jwt_enc.key", 2048)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
err = j.WithEncryption(jwt.A128CBCHS256, jwt.RSA15, encKey)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
/*
|
||||
func hmac_Example() {
|
||||
// hmac
|
||||
key := []byte("secret")
|
||||
j, err := jwt.New(15*time.Minute, jwt.HS256, key)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
// OPTIONAL encryption:
|
||||
encryptionKey := []byte("itsa16bytesecret")
|
||||
err = j.WithEncryption(jwt.A128GCM, jwt.DIRECT, encryptionKey)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
/*
|
||||
func load_From_File_With_Password_Example() {
|
||||
b, err := ioutil.ReadFile("./rsa_password_protected.key")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
signKey,err := jwt.ParseRSAPrivateKey(b, []byte("pass"))
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
j, err := jwt.New(15*time.Minute, jwt.RS256, signKey)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
/*
|
||||
func generate_RSA_Example() {
|
||||
signKey, err := rsa.GenerateKey(rand.Reader, 4096)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
encryptionKey, err := rsa.GenerateKey(rand.Reader, 4096)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
j, err := jwt.New(15*time.Minute, jwt.RS512, signKey)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
err = j.WithEncryption(jwt.A128CBCHS256, jwt.RSA15, encryptionKey)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
*/
|
||||
30
_examples/auth/jwt/rsa_password_protected.key
Normal file
30
_examples/auth/jwt/rsa_password_protected.key
Normal file
@@ -0,0 +1,30 @@
|
||||
-----BEGIN RSA PRIVATE KEY-----
|
||||
Proc-Type: 4,ENCRYPTED
|
||||
DEK-Info: DES-EDE3-CBC,6B0BC214C94124FE
|
||||
|
||||
lAM48DEM/GdCDimr9Vhi+fSHLgduDb0l2BA4uhILgNby51jxY/4X3IqM6f3ImKX7
|
||||
cEd9OBug+pwIugB0UW0L0f5Pd59Ovpiaz3xLci1/19ehYnMqsuP3YAnJm40hT5VP
|
||||
p0gWRiR415PJ0fPeeJPFx5IsqvkTJ30LWZHUZX4EkdcL5L8PrVbmthGDbLh+OcMc
|
||||
LzoP8eTglzlZF03nyvAol6+p2eZtvOJLu8nWG25q17kyBx6kEiCsWFcUBTX9G7sH
|
||||
CM3naByDijqZXE/XXtmTMLSRRnlk7Q5WLxClroHlUP9y8BQFMo2TW4Z+vNjHUkc1
|
||||
77ghabX1704bAlIE8LLZJKrm/C5+VKyV6117SVG/2bc4036Y5rStXpANbk1j4K0x
|
||||
ADvpRhuTpifaogdvJP+8eXBdl841MQMRzWuZHp6UNYYQegoV9C+KHyJx4UPjZyzd
|
||||
gblZmKgU+BsX3mV6MLhJtd6dheLZtpBsAlSstJxzmgwqz9faONYEGeItXO+NnxbA
|
||||
mxAp/mI+Fz2jfgYlWjwkyPPzD4k/ZMMzB4XLkKKs9XaxUtTomiDkuYZfnABhxt73
|
||||
xBy40V1rb/NyeW80pk1zEHM6Iy/48ETSp9U3k9sSOXjMhYbPXgxDtimV8w0qGFAo
|
||||
2Tif7ZuaiuC38rOkoHK9C6vy2Dp8lQZ+QBnUKLeFsyhq9CaqSdnyUTMj3oEZXXf+
|
||||
TqqeO+PTtl7JaNfGRq6/aMZqxACHkyVUvYvjZzx07CJ2fr+OtNqxallM6Oc/o9NZ
|
||||
5u7lpgrYaKM/b67q0d2X/AoxR5zrZuM8eam3acD1PwHFQKbJWuFNmjWtnlZNuR3X
|
||||
fZEmxIKwDlup8TxFcqbbZtPHuQA2mTMTqfRkf8oPSO+N6NNaUpb0ignYyA7Eu5GT
|
||||
b02d/oNLETMikxUxntMSH7GhuOpfJyELz8krYTttbJ+a93h4wBeYW2+LyAr/cRLB
|
||||
mbtKLtaN7f3FaOSnu8e0+zlJ7xglHPXqblRL9q6ZDM5UJtJD4rA7LPZHk/0Y1Kb6
|
||||
hBh1qMDu0r3IV4X7MDacvxw7aa7D8TyXJiFSvxykVhds+ndjIe51Ics5908+lev3
|
||||
nwE69PLMwyqe2vvE2oDwao4XJuBLCHjcv/VagRSz/XQGMbZqb3L6unyd3UPl8JjP
|
||||
ovipNwM4rFnE54uiUUeki7TZGDYO72vQcSaLrmbeAWc2m202+rqLz0WMm6HpPmCv
|
||||
IgexpX2MnIeHJ3+BlEjA2u+S6xNSD7qHGk2pb7DD8nRvUdSHAHeaQbrkEfEhhR2Q
|
||||
Dw5gdw1JyQ0UKBl5ndn/1Ub2Asl016lZjpqHyMIVS4tFixACDsihEYMmq/zQmTj4
|
||||
8oBZTU+fycN/KiGKZBsqxIwgYIeMz/GfvoyN5m57l6fwEZALVpveI1pP4fiZB/Z8
|
||||
xLKa5JK6L10lAD1YHWc1dPhamf9Sb3JwN2CFtGvjOJ/YjAZu3jJoxi40DtRkE3Rh
|
||||
HI8Cbx1OORzoo0kO0vy42rz5qunYyVmEzPKtOj+YjVEhVJ85yJZ9bTZtuyqMv8mH
|
||||
cnwEeIFK8cmm9asbVzQGDwN/UGB4cO3LrMX1RYk4GRttTGlp0729BbmZmu00RnD/
|
||||
-----END RSA PRIVATE KEY-----
|
||||
118
_examples/auth/permissions/main.go
Normal file
118
_examples/auth/permissions/main.go
Normal file
@@ -0,0 +1,118 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"strings"
|
||||
|
||||
"github.com/kataras/iris/v12"
|
||||
|
||||
permissions "github.com/xyproto/permissionbolt"
|
||||
// * PostgreSQL support:
|
||||
// permissions "github.com/xyproto/pstore" and
|
||||
// perm, err := permissions.New(...)
|
||||
//
|
||||
// * MariaDB/MySQL support:
|
||||
// permissions "github.com/xyproto/permissionsql" and
|
||||
// perm, err := permissions.New/NewWithDSN(...)
|
||||
// * Redis support:
|
||||
// permissions "github.com/xyproto/permissions2"
|
||||
// perm, err := permissions.New2()
|
||||
// * Bolt support (this one):
|
||||
// permissions "github.com/xyproto/permissionbolt" and
|
||||
// perm, err := permissions.New(...)
|
||||
)
|
||||
|
||||
func main() {
|
||||
app := iris.New()
|
||||
app.Logger().SetLevel("debug")
|
||||
|
||||
// New permissions middleware.
|
||||
perm, err := permissions.New()
|
||||
if err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
|
||||
// Blank slate, no default permissions
|
||||
// perm.Clear()
|
||||
|
||||
// Set up a middleware handler for Iris, with a custom "permission denied" message.
|
||||
permissionHandler := func(ctx iris.Context) {
|
||||
// Check if the user has the right admin/user rights
|
||||
if perm.Rejected(ctx.ResponseWriter(), ctx.Request()) {
|
||||
// Deny the request, don't call other middleware handlers
|
||||
ctx.StopWithText(iris.StatusForbidden, "Permission denied!")
|
||||
return
|
||||
}
|
||||
// Call the next middleware handler
|
||||
ctx.Next()
|
||||
}
|
||||
|
||||
// Register the permissions middleware
|
||||
app.Use(permissionHandler)
|
||||
|
||||
// Get the userstate, used in the handlers below
|
||||
userstate := perm.UserState()
|
||||
|
||||
app.Get("/", func(ctx iris.Context) {
|
||||
msg := ""
|
||||
msg += fmt.Sprintf("Has user bob: %v\n", userstate.HasUser("bob"))
|
||||
msg += fmt.Sprintf("Logged in on server: %v\n", userstate.IsLoggedIn("bob"))
|
||||
msg += fmt.Sprintf("Is confirmed: %v\n", userstate.IsConfirmed("bob"))
|
||||
msg += fmt.Sprintf("Username stored in cookies (or blank): %v\n", userstate.Username(ctx.Request()))
|
||||
msg += fmt.Sprintf("Current user is logged in, has a valid cookie and *user rights*: %v\n", userstate.UserRights(ctx.Request()))
|
||||
msg += fmt.Sprintf("Current user is logged in, has a valid cookie and *admin rights*: %v\n", userstate.AdminRights(ctx.Request()))
|
||||
msg += fmt.Sprintln("\nTry: /register, /confirm, /remove, /login, /logout, /makeadmin, /clear, /data and /admin")
|
||||
ctx.WriteString(msg)
|
||||
})
|
||||
|
||||
app.Get("/register", func(ctx iris.Context) {
|
||||
userstate.AddUser("bob", "hunter1", "bob@zombo.com")
|
||||
ctx.Writef("User bob was created: %v\n", userstate.HasUser("bob"))
|
||||
})
|
||||
|
||||
app.Get("/confirm", func(ctx iris.Context) {
|
||||
userstate.MarkConfirmed("bob")
|
||||
ctx.Writef("User bob was confirmed: %v\n", userstate.IsConfirmed("bob"))
|
||||
})
|
||||
|
||||
app.Get("/remove", func(ctx iris.Context) {
|
||||
userstate.RemoveUser("bob")
|
||||
ctx.Writef("User bob was removed: %v\n", !userstate.HasUser("bob"))
|
||||
})
|
||||
|
||||
app.Get("/login", func(ctx iris.Context) {
|
||||
// Headers will be written, for storing a cookie
|
||||
userstate.Login(ctx.ResponseWriter(), "bob")
|
||||
ctx.Writef("bob is now logged in: %v\n", userstate.IsLoggedIn("bob"))
|
||||
})
|
||||
|
||||
app.Get("/logout", func(ctx iris.Context) {
|
||||
userstate.Logout("bob")
|
||||
ctx.Writef("bob is now logged out: %v\n", !userstate.IsLoggedIn("bob"))
|
||||
})
|
||||
|
||||
app.Get("/makeadmin", func(ctx iris.Context) {
|
||||
userstate.SetAdminStatus("bob")
|
||||
ctx.Writef("bob is now administrator: %v\n", userstate.IsAdmin("bob"))
|
||||
})
|
||||
|
||||
app.Get("/clear", func(ctx iris.Context) {
|
||||
userstate.ClearCookie(ctx.ResponseWriter())
|
||||
ctx.WriteString("Clearing cookie")
|
||||
})
|
||||
|
||||
app.Get("/data", func(ctx iris.Context) {
|
||||
ctx.WriteString("user page that only logged in users must see!")
|
||||
})
|
||||
|
||||
app.Get("/admin", func(ctx iris.Context) {
|
||||
ctx.WriteString("super secret information that only logged in administrators must see!\n\n")
|
||||
if usernames, err := userstate.AllUsernames(); err == nil {
|
||||
ctx.Writef("list of all users: %s" + strings.Join(usernames, ", "))
|
||||
}
|
||||
})
|
||||
|
||||
// Serve
|
||||
app.Listen(":8080")
|
||||
}
|
||||
44
_examples/auth/recaptcha/custom_form/main.go
Normal file
44
_examples/auth/recaptcha/custom_form/main.go
Normal file
@@ -0,0 +1,44 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/kataras/iris/v12"
|
||||
|
||||
"github.com/kataras/iris/v12/middleware/recaptcha"
|
||||
)
|
||||
|
||||
// keys should be obtained by https://www.google.com/recaptcha
|
||||
const (
|
||||
recaptchaPublic = "6Lf3WywUAAAAAKNfAm5DP2J5ahqedtZdHTYaKkJ6"
|
||||
recaptchaSecret = "6Lf3WywUAAAAAJpArb8nW_LCL_PuPuokmEABFfgw"
|
||||
)
|
||||
|
||||
func main() {
|
||||
app := iris.New()
|
||||
|
||||
r := recaptcha.New(recaptchaSecret)
|
||||
|
||||
app.Get("/comment", showRecaptchaForm)
|
||||
|
||||
// pass the middleware before the main handler or use the `recaptcha.SiteVerify`.
|
||||
app.Post("/comment", r, postComment)
|
||||
|
||||
app.Listen(":8080")
|
||||
}
|
||||
|
||||
var htmlForm = `<form action="/comment" method="POST">
|
||||
<script src="https://www.google.com/recaptcha/api.js"></script>
|
||||
<div class="g-recaptcha" data-sitekey="%s"></div>
|
||||
<input type="submit" name="button" value="Verify">
|
||||
</form>`
|
||||
|
||||
func showRecaptchaForm(ctx iris.Context) {
|
||||
contents := fmt.Sprintf(htmlForm, recaptchaPublic)
|
||||
ctx.HTML(contents)
|
||||
}
|
||||
|
||||
func postComment(ctx iris.Context) {
|
||||
// [...]
|
||||
ctx.JSON(iris.Map{"success": true})
|
||||
}
|
||||
40
_examples/auth/recaptcha/main.go
Normal file
40
_examples/auth/recaptcha/main.go
Normal file
@@ -0,0 +1,40 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"github.com/kataras/iris/v12"
|
||||
"github.com/kataras/iris/v12/middleware/recaptcha"
|
||||
)
|
||||
|
||||
// keys should be obtained by https://www.google.com/recaptcha
|
||||
const (
|
||||
recaptchaPublic = ""
|
||||
recaptchaSecret = ""
|
||||
)
|
||||
|
||||
func showRecaptchaForm(ctx iris.Context, path string) {
|
||||
ctx.HTML(recaptcha.GetFormHTML(recaptchaPublic, path))
|
||||
}
|
||||
|
||||
func main() {
|
||||
app := iris.New()
|
||||
|
||||
// On both Get and Post on this example, so you can easly
|
||||
// use a single route to show a form and the main subject if recaptcha's validation result succeed.
|
||||
app.HandleMany("GET POST", "/", func(ctx iris.Context) {
|
||||
if ctx.Method() == iris.MethodGet {
|
||||
showRecaptchaForm(ctx, "/")
|
||||
return
|
||||
}
|
||||
|
||||
result := recaptcha.SiteVerify(ctx, recaptchaSecret)
|
||||
if !result.Success {
|
||||
/* redirect here if u want or do nothing */
|
||||
ctx.HTML("<b> failed please try again </b>")
|
||||
return
|
||||
}
|
||||
|
||||
ctx.Writef("succeed.")
|
||||
})
|
||||
|
||||
app.Listen(":8080")
|
||||
}
|
||||
Reference in New Issue
Block a user