I am having trouble with a Go Buffalo web app I am trying to build. I basically have a standard form on the front end that, when clicked, is supposed to send a tweet to the Users twitter account.
I get a “500: CSRF Not found” when doing so.
I am using the Go Buffalo framework for the web app and go-twitter to handle the twitter API.
I have little to no experience with CSRF so was hoping somebody could help me in this specific case.
The tweet.HTML:
<h3>Tweet tweet!</h3>
<form action="/tweet" method="POST">
<div class="form-group">
<label for="tweet">Your tweet:</label>
<input type="text" name="tweet" class="form-control" id="tweet" placeholder="Tweet body"
value="">
</div>
<button type="submit" class="btn btn-primary">Send</button>
</form>
The router:
app.POST("/tweet", SendHandler)
Tweet.go (Contains SendHandler function):
package actions
import (
"fmt"
"log"
"os"
"twitapp/twitter"
"github.com/gobuffalo/buffalo"
)
var creds = twitter.Credentials{
AccessToken: os.Getenv("ACCESS_TOKEN"),
AccessTokenSecret: os.Getenv("ACCESS_TOKEN_SECRET"),
APIKey: os.Getenv("API_KEY"),
APISecret: os.Getenv("API_SECRET"),
}
type TweetForm struct {
TweetBody string
}
// TweetHandler is the handler for the Tweet page
func TweetHandler(c buffalo.Context) error {
return c.Render(200, r.HTML("tweet.html"))
}
//SendHandler Function used by tweet.html to send the tweet/
//Takes in variables from twitter/server.go
func SendHandler(c buffalo.Context) error {
var form TweetForm
body := form.TweetBody
fmt.Printf("%+vn", creds)
//Gets the client from the twitter package
client, err := twitter.GetClient(&creds)
if err != nil {
log.Println("Error getting Twitter Client")
log.Println(err)
}
//Sending the actual tweet. Body from the form
tweet, resp, err := client.Statuses.Update(body, nil)
if err != nil {
log.Println(err)
}
log.Printf("%+vn", resp)
log.Printf("%+vn", tweet)
return c.Redirect(302, "/tweet/confirm")
}
There is also a GetClient function that is called from the SendHandler function but I cant imagine the problem is in there as it standard code that sets up the twitter client for the call.
Appreciate any help/pointing in the right direction. I dont have enough knowledge of CSRF to apply it to this at the moment.
2
Answers
After looking through the GoBuffalo docs, and in particular THIS part of the forms page, All i had to do was add this line of code to my form (tweet.html) to handle the authenticity token.
CSRF is a kind of attack Buffalo is trying to protect you from.
To do that, it uses the CSRF middleware which checks every request which can mutate your data (eg. POST, PUT, DELETE, etc.) and looks for a specific token. In your use-case, Buffalo expects you to send an input field named “authenticity_token”, with the value the CSRF middleware put in the context. You can find this value at the same “authenticity_token” key in the context.
Another solution is to use the tags helpers (https://github.com/gobuffalo/tags) library which generates this expected input for you: https://github.com/gobuffalo/tags/wiki/Form