5
0
mirror of https://github.com/wailsapp/wails.git synced 2025-05-09 19:02:00 +08:00

[v3] Add provider methods, provide default login window, update readme for oauth plugin

This commit is contained in:
Lea Anthony 2023-07-09 12:30:36 +10:00
parent 1d562d3c27
commit 3f55ce6dfc
No known key found for this signature in database
GPG Key ID: 33DAF7BB90A58405
3 changed files with 508 additions and 33 deletions

View File

@ -41,15 +41,6 @@ func main() {
},
})
oAuthWindow := app.NewWebviewWindowWithOptions(application.WebviewWindowOptions{
Title: "Login",
Width: 600,
Height: 850,
Hidden: true,
DisableResize: true,
URL: "http://localhost:9876/auth/github",
})
app.NewWebviewWindowWithOptions(application.WebviewWindowOptions{
Title: "OAuth Demo",
DevToolsEnabled: true,
@ -61,17 +52,8 @@ func main() {
},
})
// Custom event handling
app.Events.On(oauth.Success, func(e *application.WailsEvent) {
oAuthWindow.Hide()
})
app.Events.On(oauth.Error, func(e *application.WailsEvent) {
oAuthWindow.Hide()
})
app.Events.On("github-login", func(e *application.WailsEvent) {
oAuthPlugin.Start()
oAuthWindow.Show()
oAuthPlugin.Github()
})
err := app.Run()

View File

@ -1,10 +1,71 @@
# oauth Plugin
This plugin provides the ability to initiate an OAuth authentication flow.
This plugin provides the ability to initiate an OAuth authentication flow with a wide range of OAuth providers:
- Amazon
- Apple
- Auth0
- AzureAD
- BattleNet
- Bitbucket
- Box
- Dailymotion
- Deezer
- DigitalOcean
- Discord
- Dropbox
- EveOnline
- Facebook
- Fitbit
- Gitea
- Gitlab
- Github
- Google
- GooglePlus
- Heroku
- Intercom
- Instagram
- Kakao
- LastFM
- LinkedIn
- Line
- Mastodon
- Meetup
- MicrosoftOnline
- Naver
- NextCloud
- Okta
- Onedrive
- OpenIDConnect
- Patreon
- PayPal
- SalesForce
- SeaTalk
- Shopify
- Slack
- SoundCloud
- Spotify
- Steam
- Strava
- Stripe
- TikTok
- Twitter
- TwitterV2
- Typetalk
- Twitch
- Uber
- VK
- WeCom
- Wepay
- Xero
- Yahoo
- Yammer
- Yandex
- Zoom
## Installation
Add the plugin to the `Plugins` option in the Applications options:
Add the plugin to the `Plugins` option in the Applications options. This example we are using the github provider:
```go
package main
@ -34,20 +95,109 @@ func main() {
})
```
### Configuration
The plugin takes a `Config` struct as a parameter. This struct has the following fields:
```go
type Config struct {
// Address to bind the temporary webserver to
// Defaults to localhost:9876
Address string
// SessionSecret is the secret used to encrypt the session store.
SessionSecret string
// MaxAge is the maximum age of the session in seconds.
MaxAge int
// Providers is a list of goth providers to use.
Providers []goth.Provider
// WindowConfig is the configuration for the window that will be opened
// to perform the OAuth login.
WindowConfig *application.WebviewWindowOptions
}
```
If you don't specify a `WindowConfig`, the plugin will use the default window configuration:
```go
&application.WebviewWindowOptions{
Title: "OAuth Login",
Width: 600,
Height: 850,
Hidden: true,
}
```
## Usage
### Go
You can start the flow by calling `Start()` on the plugin instance:
You can start the flow by calling one of the provider methods:
```go
err := oAuthPlugin.Github()
```
In this example, we send an event from the frontend to start the process, so we listen for the event in the backend:
```go
app.Events.On("github-login", func(e *application.WailsEvent) {
oAuthPlugin.Start()
oAuthWindow.Show()
err := oAuthPlugin.Github()
if err != nil {
// process error
}
})
```
There is a working example of github auth in the `v3/examples` directory.
### JavaScript
You can start the flow by calling one of the provider methods:
```javascript
await wails.Plugin("oauth","Github")
```
### Handling Success & Failure
When the OAuth flow completes, the plugin will send one of 2 events:
- `wails:oauth:success` - The OAuth flow completed successfully. The event data will contain the user information.
- `wails:oauth:error` - The OAuth flow failed. The event data will contain the error message.
In Javascript, we can listen for these events like so:
```javascript
window.wails.Events.On("wails:oauth:success", (event) => {
document.getElementById("main").style.display = "none";
document.getElementById("name").innerText = event.data.Name;
document.getElementById("logo").src = event.data.AvatarURL;
document.body.style.backgroundColor = "#000";
document.body.style.color = "#FFF";
});
```
If you want to handle them in Go, you can do so like this:
```go
app.Events.On("wails:oauth:success", func(e *application.WailsEvent) {
// Do something with the user data
})
```
Both these events are constants in the plugin:
```go
const (
Success = "wails:oauth:success"
Error = "wails:oauth:error"
)
```
There is a working example of GitHub auth in the `v3/examples/oauth` directory.
## Support

View File

@ -1,6 +1,7 @@
package oauth
import (
"fmt"
"github.com/gorilla/pat"
"github.com/gorilla/sessions"
"github.com/markbates/goth"
@ -40,6 +41,10 @@ type Config struct {
// Providers is a list of goth providers to use.
Providers []goth.Provider
// WindowConfig is the configuration for the window that will be opened
// to perform the OAuth login.
WindowConfig *application.WebviewWindowOptions
}
func NewPlugin(config Config) *Plugin {
@ -52,6 +57,14 @@ func NewPlugin(config Config) *Plugin {
if result.config.Address == "" {
result.config.Address = "localhost:9876"
}
if result.config.WindowConfig == nil {
result.config.WindowConfig = &application.WebviewWindowOptions{
Title: "OAuth Login",
Width: 600,
Height: 850,
Hidden: true,
}
}
return result
}
@ -109,7 +122,66 @@ func (p *Plugin) Init(_ *application.App) error {
func (p *Plugin) CallableByJS() []string {
return []string{
"Start",
"Amazon",
"Apple",
"Auth0",
"AzureAD",
"BattleNet",
"Bitbucket",
"Box",
"Dailymotion",
"Deezer",
"DigitalOcean",
"Discord",
"Dropbox",
"EveOnline",
"Facebook",
"Fitbit",
"Gitea",
"Gitlab",
"Github",
"Google",
"GooglePlus",
"Heroku",
"Intercom",
"Instagram",
"Kakao",
"LastFM",
"LinkedIn",
"Line",
"Mastodon",
"Meetup",
"MicrosoftOnline",
"Naver",
"NextCloud",
"Okta",
"Onedrive",
"OpenIDConnect",
"Patreon",
"PayPal",
"SalesForce",
"SeaTalk",
"Shopify",
"Slack",
"SoundCloud",
"Spotify",
"Steam",
"Strava",
"Stripe",
"TikTok",
"Twitter",
"TwitterV2",
"Typetalk",
"Twitch",
"Uber",
"VK",
"WeCom",
"Wepay",
"Xero",
"Yahoo",
"Yammer",
"Yandex",
"Zoom",
}
}
@ -117,19 +189,290 @@ func (p *Plugin) InjectJS() string {
return ""
}
// ---------------- Plugin Methods ----------------
func (p *Plugin) Start() {
func (p *Plugin) start(provider string) error {
if p.server != nil {
println("Already listening")
return
return fmt.Errorf("server already processing request. Please wait for the current login to complete")
}
p.server = &http.Server{
Addr: p.config.Address,
Handler: p.router,
}
println("Starting server")
go p.server.ListenAndServe()
time.Sleep(1 * time.Second)
// Keep trying to connect until we succeed
var keepTrying = true
var connected = false
go func() {
time.Sleep(3 * time.Second)
keepTrying = false
}()
for keepTrying {
_, err := http.Get("http://" + p.config.Address)
if err == nil {
connected = true
break
}
}
if !connected {
return fmt.Errorf("server failed to start")
}
// create a window
p.config.WindowConfig.URL = "http://" + p.config.Address + "/auth/" + provider
window := application.Get().NewWebviewWindowWithOptions(*p.config.WindowConfig)
window.Show()
application.Get().Events.On(Success, func(event *application.WailsEvent) {
window.Close()
})
application.Get().Events.On(Error, func(event *application.WailsEvent) {
window.Close()
})
return nil
}
// ---------------- Plugin Methods ----------------
func (p *Plugin) Amazon() error {
return p.start("amazon")
}
func (p *Plugin) Apple() error {
return p.start("apple")
}
func (p *Plugin) Auth0() error {
return p.start("auth0")
}
func (p *Plugin) AzureAD() error {
return p.start("azuread")
}
func (p *Plugin) BattleNet() error {
return p.start("battlenet")
}
func (p *Plugin) Bitbucket() error {
return p.start("bitbucket")
}
func (p *Plugin) Box() error {
return p.start("box")
}
func (p *Plugin) Dailymotion() error {
return p.start("dailymotion")
}
func (p *Plugin) Deezer() error {
return p.start("deezer")
}
func (p *Plugin) DigitalOcean() error {
return p.start("digitalocean")
}
func (p *Plugin) Discord() error {
return p.start("discord")
}
func (p *Plugin) Dropbox() error {
return p.start("dropbox")
}
func (p *Plugin) EveOnline() error {
return p.start("eveonline")
}
func (p *Plugin) Facebook() error {
return p.start("facebook")
}
func (p *Plugin) Fitbit() error {
return p.start("fitbit")
}
func (p *Plugin) Gitea() error {
return p.start("gitea")
}
func (p *Plugin) Gitlab() error {
return p.start("gitlab")
}
func (p *Plugin) Github() error {
return p.start("github")
}
func (p *Plugin) Google() error {
return p.start("google")
}
func (p *Plugin) GooglePlus() error {
return p.start("gplus")
}
func (p *Plugin) Heroku() error {
return p.start("heroku")
}
func (p *Plugin) Intercom() error {
return p.start("intercom")
}
func (p *Plugin) Instagram() error {
return p.start("instagram")
}
func (p *Plugin) Kakao() error {
return p.start("kakao")
}
func (p *Plugin) LastFM() error {
return p.start("lastfm")
}
func (p *Plugin) LinkedIn() error {
return p.start("linkedin")
}
func (p *Plugin) Line() error {
return p.start("line")
}
func (p *Plugin) Mastodon() error {
return p.start("mastodon")
}
func (p *Plugin) Meetup() error {
return p.start("meetup")
}
func (p *Plugin) MicrosoftOnline() error {
return p.start("microsoftonline")
}
func (p *Plugin) Naver() error {
return p.start("naver")
}
func (p *Plugin) NextCloud() error {
return p.start("nextcloud")
}
func (p *Plugin) Okta() error {
return p.start("okta")
}
func (p *Plugin) Onedrive() error {
return p.start("onedrive")
}
func (p *Plugin) OpenIDConnect() error {
return p.start("openid-connect")
}
func (p *Plugin) Patreon() error {
return p.start("patreon")
}
func (p *Plugin) PayPal() error {
return p.start("paypal")
}
func (p *Plugin) SalesForce() error {
return p.start("salesforce")
}
func (p *Plugin) SeaTalk() error {
return p.start("seatalk")
}
func (p *Plugin) Shopify() error {
return p.start("shopify")
}
func (p *Plugin) Slack() error {
return p.start("slack")
}
func (p *Plugin) SoundCloud() error {
return p.start("soundcloud")
}
func (p *Plugin) Spotify() error {
return p.start("spotify")
}
func (p *Plugin) Steam() error {
return p.start("steam")
}
func (p *Plugin) Strava() error {
return p.start("strava")
}
func (p *Plugin) Stripe() error {
return p.start("stripe")
}
func (p *Plugin) TikTok() error {
return p.start("tiktok")
}
func (p *Plugin) Twitter() error {
return p.start("twitter")
}
func (p *Plugin) TwitterV2() error {
return p.start("twitterv2")
}
func (p *Plugin) Typetalk() error {
return p.start("typetalk")
}
func (p *Plugin) Twitch() error {
return p.start("twitch")
}
func (p *Plugin) Uber() error {
return p.start("uber")
}
func (p *Plugin) VK() error {
return p.start("vk")
}
func (p *Plugin) WeCom() error {
return p.start("wecom")
}
func (p *Plugin) Wepay() error {
return p.start("wepay")
}
func (p *Plugin) Xero() error {
return p.start("xero")
}
func (p *Plugin) Yahoo() error {
return p.start("yahoo")
}
func (p *Plugin) Yammer() error {
return p.start("yammer")
}
func (p *Plugin) Yandex() error {
return p.start("yandex")
}
func (p *Plugin) Zoom() error {
return p.start("zoom")
}