mirror of
https://github.com/wailsapp/wails.git
synced 2025-05-09 21:49:56 +08:00
[v3] Add provider methods, provide default login window, update readme for oauth
plugin
This commit is contained in:
parent
1d562d3c27
commit
3f55ce6dfc
@ -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()
|
||||
|
@ -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
|
||||
|
||||
|
@ -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")
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user