mattn / go-mastodon

mastodon client for golang
MIT License
601 stars 85 forks source link

bad authorization: invalid_request while trying to connect to a gotosocial instance #169

Open noqqe opened 1 year ago

noqqe commented 1 year ago

Im trying to send a Toot to a gotosocial instance. While its working perfectly fine sending a Toot to a Mastodon Instance, it does throw an invalid_request error to gotosocial.

The code that I use for reference

func postToMastodon(text string) error {

  var c *mastodon.Client
  var t *mastodon.Toot

  // Register App
  app, err := mastodon.RegisterApp(context.Background(), &mastodon.AppConfig{
    Server:     "https://this.server/",
    ClientName: "relaystation",
    Scopes:     "read write follow",
    Website:    "urn:ietf:wg:oauth:2.0:oob",
  })
  if err != nil {
    log.Fatal(err)
  }

  // authenticate 
  c = mastodon.NewClient(&mastodon.Config{
    Server:       "https://this.server/",
    ClientID:     app.ClientID,
    ClientSecret: app.ClientSecret,
  })

  err = c.Authenticate(context.Background(), "user@example.org",  "secret")
  if err != nil {
    log.Fatal(err)
  }

  t = &mastodon.Toot{}
  t.Status = text

}

This is the error that I get

2022/12/20 11:47:53 bad authorization: 400 Bad Request: invalid_request

This is in the logs of gotosocial.

gotosocial[843043]: timestamp="20/12/2022 10:07:17.585" func=router.loggingMiddleware.func1 level=INFO latency=338.232µs clientIP=10.88.0.29 userAgent=Go-http-client/2.0 method=POST statusCode=400 path=/oauth/token msg="Bad Request: wrote 115B"

And the corresponding part on the gotosocial side of auth is https://github.com/superseriousbusiness/gotosocial/blob/694a49058951de31cca4ea061e2c08d44e712612/internal/api/client/auth/token.go#L32-L55

I'm not entirely sure what the cause, someone else having this issue or am I doing something wrong?

lmas commented 1 year ago

Had the same issue. Turned on debug logs for gotosocial and it reported missing "redirect_uri" for the c.Authenticate(..., email, password) call. Can be seen missing it in the source.

Solved it by using auth token workflow instead:

app, err := mastodon.RegisterApp( ...  
...
fmt.Println(app.AuthURI)
fmt.Println("Open this URL in your browser, login, aprove, get token and enter it here:")
var auth string
 _, err = fmt.Scanln(&auth)
...
c := mastodon.NewClient(...
...
err = c.AuthenticateToken(..., authToken, "urn:ietf:wg:oauth:2.0:oob")
...
fmt.Println("Your permanent access token is:")
fmt.Println(c.Config.AccessToken)

Do this once, when registering your application, then store your access token. Whenever you want to connect a client you simply provide the token and nothing else:

c := mastodon.NewClient(&mastodon.Config{
Server:      "localhost",
AccessToken: "yourstoredtoken",
})