Begin supporting Monzo OAuth 2.0 login flow
What's done: - Basic support of the client authorization grant stage of the OAuth login flow: - Open Google Chrome to point the user to Monzo's client authorization page. - Created a web server to retrieve the authorization code from Monzo. What's left: - Pulling the authorization grant (i.e. code) from Monzo's request and exchanging it for an access token and a refresh token, which can be used to make subsequent requests. Unanswered question: - Assuming this is a stateless app, where should I store the access token and refresh token to avoid the authorization flow. I'd like to avoid the client authorization flow because ideally I could run this app as a job that runs periodically throughout the day without requiring my interactions with it. Some interesting notes: - Notice how in the .envrc file, it's possible to make calls to `pass`. This allows me to check in the .envrc files without obscuring their content. It also allows me to consume these values in my app by using `os.Getenv("client_secret")`, which I find straightforward. Overall, I'm quite pleased to have stumbled upon this pattern - assuming that it's secure.
This commit is contained in:
parent
cce926d60f
commit
70034d4cb9
2 changed files with 43 additions and 0 deletions
2
monzo-ynab/.envrc
Normal file
2
monzo-ynab/.envrc
Normal file
|
@ -0,0 +1,2 @@
|
|||
export client_id="$(pass show finance/monzo/client-id)"
|
||||
export client_secret="$(pass show finance/monzo/client-secret)"
|
41
monzo-ynab/main.go
Normal file
41
monzo-ynab/main.go
Normal file
|
@ -0,0 +1,41 @@
|
|||
// Creating a job to import Monzo transactions into YNAB.
|
||||
//
|
||||
// This is going to run N times per 24 hours.
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"net/http"
|
||||
"os"
|
||||
"os/exec"
|
||||
)
|
||||
|
||||
var (
|
||||
clientId = os.Getenv("client_id")
|
||||
clientSecret = os.Getenv("client_secret")
|
||||
)
|
||||
|
||||
const (
|
||||
state = "xyz123"
|
||||
redirectUri = "http://localhost:8080/authorize"
|
||||
)
|
||||
|
||||
func handleRedirect(w http.ResponseWriter, r *http.Request) {
|
||||
fmt.Println(r)
|
||||
fmt.Fprintf(w, "Ackified")
|
||||
}
|
||||
|
||||
func authorizeClient() {
|
||||
url :=
|
||||
fmt.Sprintf("https://auth.monzo.com/?client_id=%s&redirect_uri=%s&response_type=code&state=:state",
|
||||
clientId, redirectUri, state)
|
||||
exec.Command("google-chrome", url).Start()
|
||||
}
|
||||
|
||||
func main() {
|
||||
authorizeClient()
|
||||
http.HandleFunc("/authorize", handleRedirect)
|
||||
go log.Fatal(http.ListenAndServe(":8080", nil))
|
||||
}
|
Loading…
Reference in a new issue